Dies wird in C # 7.3 (Framework 4.8) korrekt kompiliert:
(string, string) s = ("a", "b");
(object, string) o = s;
Ich weiß, dass dies syntaktischer Zucker für Folgendes ist, der auch korrekt kompiliert wird:
ValueTuple<string, string> s = new ValueTuple<string, string>("a", "b");
ValueTuple<object, string> o = s;
Es scheint also, dass ValueTuples kovariant zugewiesen werden können , was großartig ist !
Leider verstehe ich nicht warum : Ich hatte den Eindruck, dass C # nur Kovarianz auf Schnittstellen und Delegaten unterstützt . ValueType
ist weder.
Wenn ich versuche, diese Funktion mit meinem eigenen Code zu duplizieren, scheitere ich tatsächlich:
struct MyValueTuple<A, B>
{
public A Item1;
public B Item2;
public MyValueTuple(A item1, B item2)
{
Item1 = item1;
Item2 = item2;
}
}
...
MyValueTuple<string, string> s = new MyValueTuple<string, string>("a", "b");
MyValueTuple<object, string> o = s;
// ^ Cannot implicitly convert type 'MyValueTuple<string, string>' to 'MyValueTuple<object, string>'
Also, warum können ValueTuple
s kovariant zugewiesen werden, aber MyValueTuple
nicht?
c#
covariance
valuetuple
Heinzi
quelle
quelle
null
um ein ,Nullable<T>
obwohl es eine Struktur.ValueTuple<object, string> o = new ValueTuple<object, string>(s.Item1, s.Item2);
public static implicit operator MyValueTuple<A, B>(MyValueTuple<string, string> v) { throw new NotImplementedException(); }
der die Zuweisung dekonstruiert. Auch tolle Frage übrigens!Antworten:
Ich glaube, was hier tatsächlich passiert, ist eine destrukturierende Aufgabe. Tuple Zuordnung wird versuchen implizit auf seine Komponenten zu umwandeln, und wie es möglich ist , zuweisen
string
zuobject
, das ist , was hier passiert.Quelle
Sehen Sie es auf sharplab.io
quelle
s
Typ ändern ,(string, object)
führt dies zu einem Konvertierungsfehler, der darauf hinweist, dass eine implizite Konvertierung zwischen den Elementen stattfindet und die Zeichenfolge implizit in eine Zeichenfolge konvertiert werden kann, aber nicht umgekehrt.