Pregunta

¿Por qué está prohibido lo siguiente?

Nullable<Nullable<int>>

mientras que

struct MyNullable <T>
{


}

MyNullable<Nullable<int>> 

NO ES

¿Fue útil?

Solución

Esto se debe a que la restricción de la estructura en realidad significa 'no es nullable ' ya que Nullable, a pesar de ser una estructura, es anulable (puede aceptar el valor nulo) el Nullable < int > no es un parámetro de tipo válido para el Nullable exterior.

Esto se hace explícito en la documentación de restricciones

  

donde T: struct
  El argumento de tipo debe ser un tipo de valor. Se puede especificar cualquier tipo de valor, excepto Nullable.
  Consulte Uso de tipos anulables (Guía de programación de C #) para obtener más información.

Si desea la justificación para eso, necesitará los comentarios del diseñador del lenguaje en él, que no puedo encontrar. Sin embargo yo postularía que:

  1. el compilador y los cambios de plataforma necesarios para lograr Nullable en su forma actual son bastante extensos (y fueron una adición relativamente de último minuto a la versión 2.0).
  2. Tienen varios casos de borde potencialmente confusos.

¿Permitiendo el equivalente de int? solo confundiría que, dado que el lenguaje no proporciona una forma de distinguir entre

    Nullable < null > > y Nullable < null > , ni Nullable ni ninguna solución obvia para la siguiente.

    Nullable<Nullable<int>> x = null;
    Nullable<int> y = null;
    Console.WriteLine(x == null); // true
    Console.WriteLine(y == null); // true
    Console.WriteLine(x == y); // false or a compile time error!
    

    Hacer que el retorno sea verdadero sería muy complejo y una sobrecarga significativa en muchas operaciones que involucran el tipo Nullable.

    Algunos tipos en el CLR son 'especiales', los ejemplos son cadenas y primitivas en el sentido de que el compilador y el tiempo de ejecución saben mucho acerca de la implementación utilizada por los demás. Nullable es especial de esta manera también. Dado que ya tiene un revestimiento especial en otras áreas, el aspecto donde T: struct no es tan importante. El beneficio de esto está en tratar con estructuras en clases genéricas porque ninguna de ellas, aparte de Nullable, puede compararse con nula. Esto significa que el jit puede considerar con seguridad que t == null siempre es falso.

    Cuando los lenguajes están diseñados para permitir la interacción de dos conceptos muy diferentes, se tiende a obtener casos extraños, confusos o peligrosos. A modo de ejemplo, considere Nullable y los operadores de igualdad

    int? x = null;
    int? y = null;
    Console.WriteLine(x == y); // true
    Console.WriteLine(x >= y); // false!     
    

    Al evitar Nullables al usar la restricción genérica de la estructura, se pueden evitar muchos casos perversos (y poco claros).

    En cuanto a la parte exacta de la especificación que exige este de la sección 25.7 (énfasis mío):

      

    La restricción de tipo de valor especifica que un argumento de tipo usado para el parámetro de tipo   debe ser un tipo de valor (§25.7.1). Cualquier tipo de estructura, tipo de enumeración o tipo de estructura no anulable   el parámetro que tiene la restricción de tipo de valor satisface esta restricción. Un tipo de parametro   tener la restricción de tipo de valor no tendrá también la restricción de constructor.   El tipo System.Nullable especifica la restricción de tipo de valor no anulable para T.    Por lo tanto, los tipos construidos recursivamente de las formas T? y Nullable < Nullable < T > > están prohibidos.

Otros consejos

Creo que solo se pueden usar tipos de valores no anulables en Nullable s. Dado que Nullable en sí mismo es anulable, está prohibido anidar de esta manera.

De http://msdn.microsoft.com/en-us/library /kwxxazwb.aspx

public Nullable(
    T value
)
     

Tipo: T Un tipo de valor.

Nullable es especial porque hay un soporte explícito para el boxeo y el desempaquetado de los tipos de Nullable integrados en el CLR:

Si usa la instrucción MScode contra un Nullable < T > , obtendrá un null como resultado. No hay otro tipo de valor que produzca un valor nulo cuando esté en el recuadro.

Hay un soporte similar y simétrico para el desempaquetado.

El parámetro de tipo genérico para Nullable debe ser un tipo no anulable (es decir, tipo de valor). Esta es la advertencia del compilador de C # que recibo, y parece tener sentido. Dime, ¿por qué querrías hacer una cosa así? Personalmente, no veo ningún uso, e incluso tengo poco significado para tal declaración.

Nullable le permite tomar un tipo de valor y hacerlo como un tipo de referencia, en el sentido de que el valor existe o no (es nulo). Dado que un tipo de referencia ya es anulable, no está permitido.

Citado de MSDN :

  

La estructura anulable (T) soporta   usando solo un tipo de valor como un nullable   escribe porque los tipos de referencia son   Nullable por diseño.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top