Pourquoi est-il impossible d'appeler des méthodes statiques sur Nullable abréviations?

j'ai pensé T? est juste un raccourci de compilateur pour Nullable<T>. Selon MSDN:

La syntaxe T? est un raccourci pour Nullable<T>, où T est un type valeur. Les deux formes sont interchangeables.

cependant, il y a une petite différence (insignifiante): Visual Studio ne me permet pas d'appeler des méthodes statiques sur des raccourcis:

bool b1 = Nullable<int>.Equals(1, 2); //no error
bool b2 = int?.Equals(1, 2); //syntax error "Invalid expression term 'int'"

Pourquoi? Y a-t-il une raison à cette limitation?

24
demandé sur vojta 2017-05-31 15:57:56

2 réponses

Votre MSDN devis échos §4.1.10 de C# 5.0 spécifications:

un type nul est écrit T?, où T est le type sous-jacent. Cette syntaxe est abrégée pour System.Nullable<T>, et les deux formes peuvent être utilisés de façon interchangeable.

mais "interchangeables" est une simplification excessive. Il est vrai que T? signifie System.Nullable<T>, mais comme vous l'avez découvert, vous ne pouvez pas utiliser T? partout que vous pouvez utiliser System.Nullable<T>. En particulier, le genre de membre d'accès (§7.6.4) dans votre exemple, nécessite un simple-nom (§7.6.2):

[§7.6] les expressions primaires comprennent les formes les plus simples des expressions.

expression primaire:

  primaire-pas-tableau-création-expression

  array-création-expression

primaire-pas-tableau-création-expression

  littérale

  simple-nom

  mise entre parenthèses de l'expression

  membre d'accès

  ...

[§7.6.2]simple-nom est soit de la forme I, ou de la forme I<A1, ..., AK>, où I est un identifiant unique et <A1, ..., AK> est facultatif type de l'argument de la liste.

[§7.6.4]membre d'accès est soit de la forme E.I, ou de la forme E.I<A1, ..., AK>, où E est un expression primaire,I est un identifiant unique et <A1, ..., AK> facultatif type de l'argument de la liste.

Nullable<T> est un simple-nom et T? n'est pas le cas, l'ancien compile tandis que le second ne l'est pas.

pourquoi le C# les concepteurs de langues ont besoin d'un membre d'accès expression simple-nom plutôt tapez? Je suppose qu'ils sont les seuls à pouvoir le dire avec certitude, mais peut-être que cette exigence simplifiait la grammaire: dans une expression, le compilateur peut supposer que ? est toujours l'opérateur conditionnel (ternaire) au lieu d'un spécificateur de type éventuellement nul.

en rétrospective, cependant, ce fut un choix heureux qui a permis à C# 6.0 d'ajouter le ?. opérateur Sans peut-être casser les programmes existants. Par exemple, considérons cet exemple pathologique:

struct S
{
    public bool Equals(int x, int y) { return false; }
}

class C
{
    public static void Main()
    {
        S? S = new S();
        Console.WriteLine(S?.Equals(1, 1)); // "True" or "False"?
    }
}

Devrait S?.Equals être analysée comme Nullable<S> . Equals, un appel à Equals méthode statique de la classe Object? Ou doit-elle être analysée comme S ?. Equals, un appel null-conditionnel à Equals méthode de l'instance de la variable S? Parce que S? n'est pas simple-nom, c'est sans ambiguïté le dernier.

12
répondu Michael Liu 2017-06-06 20:24:24

alors que vous avez raison sur la syntaxe, la méthode Equals peut être appelée à partir du type par défaut en utilisant le type Nullable comme paramètre.

Vous pouvez essayer ce test avec la valeur que vous voulez :

int? i = 4;
int? j = null;
Assert.AreEqual(Nullable<int>.Equals(i, j), int.Equals(i, j));
0
répondu Aboc 2017-06-06 15:06:20