2012-12-10 1 views
15

Possible en double:
Nullable type as a generic parameter possible?Pourquoi Nullable <T> ne correspondent en tant que type de référence pour les contraintes génériques

je suis tombé sur une chose très bizarre avec des contraintes de type générique. J'ai une classe comme ceci:

public SomeClass<T> where T:class 
{ 
} 

Cependant, je l'ai trouvé, je ne peux pas utiliser les types nullables que je pense:

new SomeClass<int?>(); 

Je reçois une erreur qui int? doit être une référence type. Est-ce que Nullable est vraiment juste une structure avec du sucre syntaxique pour le faire ressembler à un type de référence?

+2

Quelle est la raison de cette contrainte? Pouvez-vous fournir plus de contexte? FYI Nullable est déclaré comme: 'public struct Nullable où T: struct' –

+0

@SimonWhitehead essentiellement parce que l'utilisation de types de valeur sur cette classe peut avoir un comportement inattendu et de grandes répercussions sur les performances – Earlz

+1

Ensuite, je suppose que la réponse directe est" oui, Nullable est un struct ". Je ne suis pas tout à fait sûr de ce que vous considérez comme du sucre syntactique pour Nullable. Il semblerait que votre seule option est de rouler la vôtre. –

Répondre

20

Nullable<T> est un struct (voir MSDN) il est cependant le seul struct qui ne satisfait pas la contrainte struct. Par conséquent, vous ne pouvez pas utiliser un Nullable en tant que paramètre de type générique lorsque les contraintes class ou struct sont utilisées.

Nullable<T> n'est pas seulement une structure avec du sucre syntatique. Il a un support spécial dans le CLR pour certains de ses comportements. Par exemple, il a un comportement spécial de boxe. Plus précisément, un nullable n'est jamais encadré. La valeur sous-jacente est encadrée. Si nullable est la valeur null (HasValue est false) alors il est converti en une référence nulle. En outre, les opérateurs de conversion pour tout Nullable<T> à Nullable<U> sont levés des conversions de T à U. Ce sont des fonctionnalités que vous ne pourriez pas implémenter dans .NET 1.0/1.1.

Questions connexes