una requiere referencia puede propiedad para objeto método metodos metodo llamar inicializador hacer estáticos estaticos estatico desde campo c# .net syntax-error nullable

c# - requiere - ¿Por qué es imposible llamar métodos estáticos en los métodos abreviados de Nullable<T>?



static void main c# (2)

Si bien tiene razón acerca de la sintaxis, el método Equals puede llamarse desde el tipo predeterminado utilizando el tipo de Nullable como parámetros.

Puedes probar esta prueba de unidad con el valor que quieras:

int? i = 4; int? j = null; Assert.AreEqual(Nullable<int>.Equals(i, j), int.Equals(i, j));

Pensé T? es solo una abreviatura del compilador para Nullable<T> . Según MSDN :

La sintaxis T? es la abreviatura de Nullable<T> , donde T es un tipo de valor. Las dos formas son intercambiables.

Sin embargo, hay una pequeña diferencia (insignificante): Visual Studio no me permite llamar a métodos estáticos en taquigrafía:

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

¿Por qué? ¿Hay alguna razón para esta limitación?


Su cita de MSDN se hace eco del §4.1.10 de la especificación C # 5.0:

Un tipo anulable se escribe T? , donde T es el tipo subyacente. Esta sintaxis es abreviada para System.Nullable<T> , y las dos formas se pueden usar indistintamente.

Pero "indistintamente" es una simplificación excesiva. Es cierto que T? significa System.Nullable<T> , pero como has descubierto, ¿no puedes usar T? En cualquier lugar que pueda usar System.Nullable<T> . En particular, el tipo de acceso de miembro (§7.6.4) en su ejemplo requiere un nombre simple (§7.6.2):

[§7.6] Las expresiones primarias incluyen las formas más simples de expresiones.

Expresión primaria:
expresión-no-matriz-primaria-expresión
array-creación-expresión

expresión-no-matriz-primaria-expresión
literal
nombre simple
expresión en paréntesis
acceso de miembros
...

[§7.6.2] Un nombre simple es de la forma I o de la forma I<A1, ..., AK> , donde I es un identificador único y <A1, ..., AK> es una opción tipo-argumento-lista .

[§7.6.4] Un acceso de miembro tiene la forma EI o la forma EI<A1, ..., AK> , donde E es una expresión primaria , I es un identificador único y <A1, ..., AK> es una lista opcional de tipo-argumento .

Nullable<T> es un nombre simple y T? no es, por lo que el primero compila mientras que el segundo no lo hace.

¿Por qué los diseñadores de lenguaje C # requirieron una expresión de acceso de miembro para usar un nombre simple en lugar de cualquier tipo ? Supongo que solo ellos pueden decir con seguridad, pero tal vez este requisito simplificó la gramática: en una expresión, el compilador puede asumir eso ? es siempre el operador condicional (ternario) en lugar de un especificador de tipo que puede contener nulos.

Sin embargo, en retrospectiva, esta fue una elección afortunada que permitió a C # 6.0 agregar el ?. Operador sin posibilidad de romper programas existentes. Por ejemplo, considere este ejemplo patológico:

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"? } }

¿Debe S?.Equals deben analizar como Nullable<S> . Equals Nullable<S> . Equals , una llamada al método estático Equals de la clase Object ? ¿O debería ser analizado como S ?. Equals S ?. Equals , ¿una llamada condicional nula al método de instancia Equals de la variable S ? Porque S? no es un nombre simple , es inequívoco el último.