Kompiluje się to poprawnie w C # 7.3 (Framework 4.8):
(string, string) s = ("a", "b");
(object, string) o = s;
Wiem, że jest to cukier składniowy dla następujących składników, który również poprawnie się kompiluje:
ValueTuple<string, string> s = new ValueTuple<string, string>("a", "b");
ValueTuple<object, string> o = s;
Wygląda więc na to, że ValueTuples można przypisywać kowariantnie , co jest niesamowite !
Niestety, nie rozumiem dlaczego : miałem wrażenie, że C # wspierał kowariancję tylko w interfejsach i delegatach . ValueType
Nie jest.
W rzeczywistości, gdy próbuję powielić tę funkcję za pomocą własnego kodu, nie udaje mi się:
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>'
Dlaczego więc można ValueTuple
go przypisać kowariantnie, MyValueTuple
a nie można?
c#
covariance
valuetuple
Heinzi
źródło
źródło
null
doNullable<T>
choćby to jest struct.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(); }
dekonstruujący przypisanie. Nawiasem mówiąc, świetne pytanie!Odpowiedzi:
Uważam, że to, co się tutaj naprawdę dzieje, to zadanie restrukturyzacji. Przypisanie krotka będzie próbować niejawnie przekonwertować jego składników, a jak to jest możliwe, aby przypisać
string
doobject
, że to, co dzieje się tutaj.Źródło
Zobacz na sharplab.io
źródło
s
na pisanie(string, object)
, spowoduje to błąd konwersji, wskazując, że zachodzi niejawna konwersja między elementami, a łańcuch można niejawnie przekonwertować na łańcuch, ale nie odwrotnie.