Wenn Sie in einem Tupel mehr als sieben Elemente haben, können Sie ein achtes Element angeben, das ein weiteres Tupel ist, und bis zu sieben Elemente definieren. Anschließend können Sie ein weiteres Tupel als achtes Element definieren. Es gibt jedoch keine Einschränkung für das 8. Element zum Zeitpunkt der Kompilierung. Zum Beispiel ist dieses Recht Code für den Compiler:Warum ist TRest in Tupel <T1... TRest> nicht eingeschränkt?
var tuple = new Tuple<int, int, int, int, int, int, int, double>
(1, 1, 1, 1, 1, 1, 1, 1d);
Auch wenn die IntelliSense-Dokumentation sagt, dass TRest ein Tuple sein muss. Sie erhalten keinen Fehler beim Schreiben oder Erstellen des Codes, er wird erst zur Laufzeit in Form einer ArgumentException angezeigt.
Sie können grob implementieren ein Tuple in ein paar Minuten, komplett mit einem Tuple-constrained 8. Element. Ich frage mich nur, warum es von der aktuellen Implementierung abgesehen wurde? Ist es möglicherweise ein Problem der Vorwärtskompatibilität, in dem sie mehr Elemente mit einer hypothetischen C# 5 hinzufügen könnten?
Kurzfassung grobe Implementierung
interface IMyTuple { }
class MyTuple<T1> : IMyTuple
{
public T1 Item1 { get; private set; }
public MyTuple(T1 item1) { Item1 = item1; }
}
class MyTuple<T1, T2> : MyTuple<T1>
{
public T2 Item2 { get; private set; }
public MyTuple(T1 item1, T2 item2) : base(item1) { Item2 = item2; }
}
class MyTuple<T1, T2, TRest> : MyTuple<T1, T2> where TRest : IMyTuple
{
public TRest Rest { get; private set; }
public MyTuple(T1 item1, T2 item2, TRest rest)
: base(item1, item2)
{
Rest = rest;
}
}
...
var mytuple = new MyTuple<int, int, MyTuple<int>>
(1, 1, new MyTuple<int>(1)); // legal
var mytuple2 = new MyTuple<int, int, int>(1, 2, 3); // illegal at compile time
Wirklich? Wie könnte man das so implementieren, dass das letzte Element als "Tupel" beliebiger Größe definiert wurde, ohne eine zusätzliche Basisklasse oder Schnittstelle zu definieren, die unter den verschiedenen generischen 'Tuple'-Größen üblich war? Ich sehe nicht, wie du denkst, dass sie das in C# machen könnten. – mquander
@mquander, Tuple implementiert ITuple. Sie können einen eigenen Tuple-Typ (MyTuple) definieren, der das letzte Element an eine Schnittstelle bindet (IMyTuple), und Sie erhalten eine Kompilierungszeitüberprüfung. –
Oh, ich wusste nichts über 'ITuple'. Danke für die Korrektur. Ich stelle fest, dass "ITuple" intern ist; vielleicht wollten sie es intern halten - wenn es eine Einschränkung wäre, müsste es öffentlich sein. – mquander