Ini mengkompilasi dengan benar dalam C # 7.3 (Kerangka 4.8):
(string, string) s = ("a", "b");
(object, string) o = s;
Saya tahu ini adalah gula sintaksis untuk yang berikut, yang juga mengkompilasi dengan benar:
ValueTuple<string, string> s = new ValueTuple<string, string>("a", "b");
ValueTuple<object, string> o = s;
Jadi, tampaknya ValueTuples dapat ditetapkan secara kovarian , yang luar biasa !
Sayangnya, saya tidak mengerti mengapa : Saya mendapat kesan bahwa C # hanya mendukung kovarians pada antarmuka dan delegasi . ValueType
bukan keduanya.
Bahkan, ketika saya mencoba menduplikasi fitur ini dengan kode saya sendiri, saya gagal:
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>'
Jadi, mengapa bisa ValueTuple
ditugaskan secara kovarian, tetapi MyValueTuple
tidak bisa?
c#
covariance
valuetuple
Heinzi
sumber
sumber
null
keNullable<T>
meskipun itu sebuah 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(); }
yang mendekonstruksi tugas tersebut. Omong-omong, pertanyaan yang bagus!Jawaban:
Saya percaya apa yang sebenarnya terjadi di sini adalah tugas merusak. Tupel tugas akan mencoba untuk secara implisit mengkonversi komponennya, dan karena mungkin untuk menetapkan
string
keobject
, itulah yang terjadi di sini.Sumber
Lihat di sharplab.io
sumber
s
untuk mengetiknya(string, object)
menghasilkan kesalahan konversi, menunjukkan bahwa konversi implisit sedang terjadi di antara item, dan string dapat secara implisit dikonversi menjadi string, tetapi tidak sebaliknya.