Isso é compilado corretamente no C # 7.3 (Framework 4.8):
(string, string) s = ("a", "b");
(object, string) o = s;
Eu sei que isso é açúcar sintático para o seguinte, que também compila corretamente:
ValueTuple<string, string> s = new ValueTuple<string, string>("a", "b");
ValueTuple<object, string> o = s;
Portanto, parece que os ValueTuples podem ser atribuídos de forma covariável , o que é incrível !
Infelizmente, não entendo o motivo : fiquei com a impressão de que o C # só suportava covariância em interfaces e delegados . ValueType
não é nenhum.
De fato, quando tento duplicar esse recurso com meu próprio código, falho:
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>'
Então, por que ValueTuple
s podem ser atribuídos covariantemente, mas MyValueTuple
s não?
c#
covariance
valuetuple
Heinzi
fonte
fonte
null
a umNullable<T>
mesmo que seja um 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(); }
desconstruir a atribuição. Além disso, ótima pergunta, a propósito!Respostas:
Acredito que o que realmente está acontecendo aqui é uma tarefa de desestruturação. A atribuição de tupla tentará converter implicitamente seus componentes e, como é possível atribuir
string
aobject
isso, é o que acontece aqui.Fonte
Veja em sharplab.io
fonte
s
para digitar,(string, object)
isso resulta em um erro de conversão, indicando que está ocorrendo uma conversão implícita entre os itens, e a string pode ser implicitamente convertida em string, mas não vice-versa.