Question

Pourquoi les éléments suivants sont-ils interdits?

Nullable<Nullable<int>>

alors que

struct MyNullable <T>
{


}

MyNullable<Nullable<int>> 

n'est PAS

Était-ce utile?

La solution

Cela est dû au fait que la contrainte de structure signifie réellement 'non nullable ' Nullable, bien qu’il soit une structure, est nullable (peut accepter la valeur null), le Nullable < int > n’est pas un paramètre de type valide pour le Nullable externe.

Ceci est explicitement expliqué dans la documentation sur les contraintes

.
  

où T: struct
  L'argument type doit être un type valeur. N'importe quel type de valeur, sauf Nullable, peut être spécifié.
  Voir Utilisation de types nullables (Guide de programmation C #) pour plus d'informations.

Si vous souhaitez en connaître les raisons, vous auriez besoin des commentaires du concepteur du langage que je ne trouve pas. Cependant, je postulerais que:

  1. les modifications du compilateur et de la plate-forme nécessaires pour atteindre Nullable dans sa forme actuelle sont assez étendues (et constituaient un ajout de dernière minute à la version 2.0).
  2. Ils ont plusieurs cas marginaux potentiellement déroutants.

Permettant l’équivalent de int ?? Cela ne ferait que confondre que, puisque le langage ne fournit aucun moyen de distinguer Nullable & Nt; Nullable < null > et Nullable < null > , ni aucune solution évidente à ce qui suit.

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!

La réalisation de ce retour serait très une surcharge complexe et significative pour de nombreuses opérations impliquant le type Nullable.

Certains types dans le CLR sont "spéciaux", les exemples sont des chaînes et des primitives en ce sens que le compilateur et le runtime en savent beaucoup sur l'implémentation utilisée l'un par l'autre. Nullable est spécial de cette façon aussi. Puisqu'il est déjà spécial dans d'autres domaines, le où l'aspect T: struct n'est pas si grave. L'avantage de ceci est de pouvoir traiter les structures dans les classes génériques car aucune d'entre elles, à l'exception de Nullable, ne peut être comparée à null. Cela signifie que le jit peut en toute sécurité considérer que t == null est toujours faux.

Lorsque les langues sont conçues pour permettre l’interaction de deux concepts très différents, vous avez tendance à faire l’objet de cas étranges, déroutants ou dangereux. A titre d'exemple, considérons Nullable et les opérateurs d'égalité

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

En empêchant Nullables lors de l’utilisation de la contrainte générique de structure, de nombreux cas délicats (et peu clairs) peuvent être évités.

En ce qui concerne la partie exacte de la spécification qui impose cette de la section 25.7 (c'est moi qui souligne):

  

La contrainte de type valeur spécifie qu'un argument de type utilisé pour le paramètre type   doit être un type de valeur (§25.7.1). Tout type de structure, type enum ou type non nullable   Le paramètre ayant la contrainte de type valeur satisfait cette contrainte. Un paramètre de type   avoir la contrainte de type valeur ne doit pas non plus avoir la contrainte constructeur.   Le type System.Nullable spécifie la contrainte de type valeur non nullable pour T.    Ainsi, types récursivement construits des formes T ?? et Nullable < Nullable < T > > sont interdits.

Autres conseils

Je pense que vous ne pouvez utiliser que des types de valeur non nullables dans les Nullable . Nullable étant lui-même nullable, l’imbrication de cette manière est interdite.

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

public Nullable(
    T value
)
     

Type: T Un type de valeur.

Nullable est spécial car il existe un support explicite pour la boxe et le déballage des types Nullable intégrés dans le CLR:

Si vous utilisez l'instruction MSIL box contre un Nullable < T > , vous obtiendrez en réalité un null . Il n'y a pas d'autre type de valeur qui produira une valeur nulle en boîte.

Il existe un support similaire et symétrique pour le déballage.

Le paramètre de type générique pour Nullable doit lui-même être un type non nullable (type de valeur). C'est l'avertissement du compilateur C # que je reçois, et cela semblerait logique. Dis-moi, pourquoi voudrais-tu faire une chose pareille? Personnellement, je ne vois aucune utilité et peu de sens à une telle déclaration, même.

Nullable vous permet de prendre un type de valeur et de le définir comme un type de référence, en ce sens que la valeur existe ou non (est null). Dans la mesure où un type de référence est déjà nullable, il n'est pas autorisé.

Cité tiré de MSDN :

  

La structure Nullable (T) prend en charge   en utilisant uniquement un type de valeur comme nullable   tapez parce que les types de référence sont   Nullable par conception.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top