web-dev-qa-db-fra.com

Qu'est-ce qui rend covariant ValueTuple?

Cela se compile correctement en C # 7.3 (Framework 4.8):

(string, string) s = ("a", "b");
(object, string) o = s;

Je sais que c'est du sucre syntaxique pour les éléments suivants, qui se compile également correctement:

ValueTuple<string, string> s = new ValueTuple<string, string>("a", "b");
ValueTuple<object, string> o = s;

Donc, il semble que ValueTuples puisse être assigné covariantly , ce qui est génial !

Malheureusement, je ne comprends pas pourquoi : j'avais l'impression que C # ne supportait que la covariance sur les interfaces et les délégués . ValueType n'est ni l'un ni l'autre.

En fait, lorsque j'essaie de dupliquer cette fonctionnalité avec mon propre code, j'échoue:

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>'

Alors, pourquoi les ValueTuples peuvent-ils être attribués de manière covariante, mais les MyValueTuples ne peuvent pas?

35
Heinzi

Je crois que ce qui se passe ici est une mission de déstructuration. L'affectation de tuple tentera de convertir implicitement ses composants, et comme il est possible d'affecter string à object, c'est ce qui se passe ici.

Le langage prend en charge l'affectation entre les types Tuple qui ont le même nombre d'éléments, où chaque élément de droite peut être implicitement converti en son élément de gauche correspondant. Les autres conversions ne sont pas prises en compte pour les affectations.

Source

Voir sur sharplab.io

25
Gareth Latty