Pergunta

Por que o seguinte é proibido?

Nullable<Nullable<int>>

enquanto

struct MyNullable <T>
{


}

MyNullable<Nullable<int>> 

NÃO é

Foi útil?

Solução

Isso ocorre porque a restrição de estrutura na verdade significa 'não anulável' já que Nullable, apesar de ser uma struct, é anulável (pode aceitar o valor null) o Nullable<int> não é um parâmetro de tipo válido para o Nullable externo.

Isto fica explícito em a documentação de restrições

onde T:estrutura
O argumento de tipo deve ser um tipo de valor.Qualquer tipo de valor, exceto Anulável, pode ser especificado.
Consulte Usando tipos anuláveis ​​(Guia de programação C#) para obter mais informações.

Se você quiser a justificativa para isso, precisará dos comentários do designer da linguagem real, que não consigo encontrar.No entanto, eu postularia que:

  1. as mudanças no compilador e na plataforma necessárias para obter o Nullable em sua forma atual são bastante extensas (e foram uma adição relativamente de última hora à versão 2.0).
  2. Eles têm vários casos extremos potencialmente confusos.

Permitindo o equivalente a int??apenas confundiria isso, uma vez que a linguagem não fornece nenhuma maneira de distinguir Nullable<Nullable<null>> e anulável<null> nem qualquer solução óbvia para o seguinte.

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!

Tornar esse retorno verdadeiro seria muito sobrecarga complexa e significativa em muitas operações envolvendo o tipo Nullable.

Alguns tipos no CLR são 'especiais', exemplos são strings e primitivos em que o compilador e o tempo de execução sabem muito sobre a implementação usada um pelo outro.Nullable também é especial nesse sentido.Como já existe revestimento especial em outras áreas, o revestimento especial do where T : struct aspecto não é grande coisa.O benefício disso é lidar com estruturas em classes genéricas porque nenhuma delas, exceto Nullable, pode ser comparada com null.Isso significa que o jit pode considerar com segurança t == null ser falso sempre.

Onde as linguagens são projetadas para permitir a interação de dois conceitos muito diferentes, você tende a ficar estranho, confuso ou em casos extremos perigosos.Como exemplo, considere Nullable e os operadores de igualdade

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

Ao evitar Nullables ao usar a restrição genérica de struct, muitos casos extremos desagradáveis ​​​​(e pouco claros) podem ser evitados.

Quanto à parte exata da especificação que exige isso da seção 25.7 (ênfase minha):

A restrição de tipo de valor especifica que um argumento de tipo usado para o parâmetro de tipo deve ser um tipo de valor (§25.7.1).Qualquer tipo de struct não anulável, tipo de enum ou tipo parâmetro com a restrição de tipo de valor satisfaz essa restrição.Um parâmetro de tipo ter a restrição de tipo de valor também não deve ter a restrição de construtor.O tipo System.Nullable especifica a restrição de tipo de valor não anulável para T. Assim, tipos construídos recursivamente das formas T??e anulável<Anulável<T>> são proibidos.

Outras dicas

Eu acredito que você só pode usar tipos de valor não nulos em Nullables. Desde Nullable É proibido o nulo, é proibido nidificar dessa maneira.

A partir de http://msdn.microsoft.com/en-us/library/kwxxazwb.aspx

public Nullable(
    T value
)

TIPO: TIPO DE VALOR TA.

Nullable é especial porque há suporte explícito para boxing e unboxing de tipos Nullable incorporados ao CLR:

Se você usa o MSIL box instrução contra um Nullable<T>, você realmente obterá um null como resultado.Não há outro tipo de valor que produza um nulo quando colocado em caixa.

Há suporte semelhante e simétrico para unboxing.

O parâmetro do tipo genérico para o NULLABLE DEVE ser um tipo não indicado (IE Tipo de valor). Este é o aviso do compilador C# que recebo, e parece fazer sentido. Diga -me, por que você gostaria de fazer uma coisa dessas? Pessoalmente, não vejo utilidade e pouco significado a essa declaração.

Anulável permite pegar um tipo de valor e torná-lo um tipo de referência, no sentido de que o valor existe ou não (é nulo).Como um tipo de referência já é anulável, isso não é permitido.

Citado de MSDN:

A estrutura Nullable(T) suporta Usando apenas um tipo de valor como anulável tipo porque os tipos de referência são anulável por design.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top