Domanda

Perché è vietato quanto segue?

Nullable<Nullable<int>>

considerando

struct MyNullable <T>
{


}

MyNullable<Nullable<int>> 

NON è

È stato utile?

Soluzione

Questo perché il vincolo della struttura in realtà significa 'not nullable ' poiché Nullable, nonostante sia una struttura, è nullable (può accettare il valore null) il Nullable < int > non è un parametro di tipo valido per la Nullable esterna.

Questo è reso esplicito in la documentazione sui vincoli

  

dove T: struct
  L'argomento type deve essere un tipo di valore. È possibile specificare qualsiasi tipo di valore tranne Nullable.
  Vedere Uso dei tipi nullable (Guida per programmatori C #) per ulteriori informazioni.

Se vuoi la logica per questo, avresti bisogno dei commenti del designer linguistico che non riesco a trovare. Tuttavia vorrei postulare che:

  1. le modifiche al compilatore e alla piattaforma richieste per ottenere Nullable nella sua forma attuale sono piuttosto estese (ed erano un'aggiunta relativamente last minute alla versione 2.0).
  2. Hanno diversi casi limite potenzialmente confusi.

Consentire l'equivalente di int ?? confonderebbe solo il fatto che la lingua non fornisce alcun modo per distinguere Nullable < Nullable < null > > e Nullable < null > né alcuna soluzione ovvia a quanto segue.

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!

Rendere vero questo ritorno sarebbe sovraccarico molto complesso e significativo su molte operazioni che coinvolgono il tipo Nullable.

Alcuni tipi nel CLR sono "speciali", esempi sono stringhe e primitive in quanto il compilatore e il runtime conoscono molto sull'implementazione utilizzata l'uno dall'altro. Nullable è speciale anche in questo modo. Dal momento che è già inserito in altre aree, il caso in cui l'aspetto dove T: struct non è un grosso problema. Il vantaggio di ciò è nel gestire strutture in classi generiche perché nessuna di esse, a parte Nullable, può essere paragonata a null. Ciò significa che il jit può tranquillamente considerare t == null sempre falso.

Laddove le lingue sono progettate per consentire l'interazione di due concetti molto diversi, si tende a creare casi strani, confusi o decisamente pericolosi. Ad esempio, considera Nullable e gli operatori di uguaglianza

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

Impedendo Nullables quando si utilizza il vincolo generico struct, è possibile evitare molti casi limite (e poco chiari) di margine.

Per quanto riguarda la parte esatta delle specifiche che impone questo dalla sezione 25.7 (sottolineatura mia):

  

Il vincolo del tipo di valore specifica che un argomento di tipo viene utilizzato per il parametro type   deve essere un tipo di valore (§25.7.1). Qualsiasi tipo di struttura, tipo enum o tipo non annullabile   il parametro con il vincolo del tipo di valore soddisfa questo vincolo. Un parametro di tipo   avere il vincolo del tipo di valore non deve avere anche il vincolo del costruttore.   Il tipo System.Nullable specifica il vincolo del tipo di valore non nullable per T.    Quindi, tipi ricorsivamente costruiti delle forme T ?? e Nullable < Nullable < T > > sono vietati.

Altri suggerimenti

Credo che puoi usare tipi di valore non annullabili in Nullable s. Poiché Nullable stesso è nullable, la nidificazione in questo modo è vietata.

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

public Nullable(
    T value
)
     

Tipo: T Un tipo di valore.

Nullable è speciale perché esiste un supporto esplicito per il boxing e unboxing dei tipi Nullable integrati nel CLR:

Se usi l'istruzione MSIL box contro un Nullable < T > , otterrai effettivamente un null come risultato. Non esiste un altro tipo di valore che produrrà un valore null se inscatolato.

Esiste un supporto simile e simmetrico per unboxing.

Il parametro di tipo generico per Nullable deve essere di per sé un tipo non annullabile (ovvero un tipo di valore). Questo è l'avvertimento del compilatore C # che ricevo e sembrerebbe avere senso. Dimmi, perché dovresti fare comunque una cosa del genere? Personalmente non riesco a vedere alcun uso e scarso significato persino per una simile dichiarazione.

Nullable ti consente di prendere un tipo di valore e renderlo come un tipo di riferimento, nel senso che il valore esiste o no (è nullo). Poiché un tipo di riferimento è già nullable, non è consentito.

Citato da MSDN :

  

La struttura Nullable (T) supporta   usando solo un tipo di valore come nullable   digitare perché i tipi di riferimento sono   nullable dal design.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top