Это правильно компилируется в C # 7.3 (Framework 4.8):
(string, string) s = ("a", "b");
(object, string) o = s;
Я знаю, что это синтаксический сахар для следующего, который также правильно компилируется:
ValueTuple<string, string> s = new ValueTuple<string, string>("a", "b");
ValueTuple<object, string> o = s;
Итак, похоже, что ValueTuples могут быть назначены ковариантно , что потрясающе !
К сожалению я не понимаю почему : у меня сложилось впечатление, что C # поддерживает ковариацию только для интерфейсов и делегатов . ValueType
это ни то, ни другое
Фактически, когда я пытаюсь продублировать эту функцию собственным кодом, у меня не получается:
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>'
Итак, почему ValueTuple
s можно назначать ковариантно, ноMyValueTuple
s нет?
c#
covariance
valuetuple
Heinzi
источник
источник
null
для негоNullable<T>
даже если это структура.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(); }
его деконструкции присваивания. Кроме того, отличный вопрос, кстати!Ответы:
Я считаю, что то, что на самом деле здесь происходит, является деструктивным заданием. Назначение Кортеж будет пытаться неявно преобразовать его компоненты, и как можно назначить
string
дляobject
, это то , что здесь происходит.Источник
Смотрите это на sharplab.io
источник
s
тип,(string, object)
это приведет к ошибке преобразования, указывающей на то, что неявное преобразование происходит между элементами, и строка может быть неявно преобразована в строку, но не наоборот.