2010-10-05 11 views

Répondre

18
type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>) 

Vous pouvez également trouver Nullable.GetUnderlyingType(Type nullableType) utile, pour obtenir facilement le T du typeof(Nullable<T>) vous passez

+0

Nice! Merci. (J'oublie toujours '<>' dans la réflexion.) –

+0

Cela ne fonctionnera pas dans beaucoup de situations courantes puisque le CLR traite 'Nullable ' comme un type spécial. En particulier, il est encadré dans un 'T' en boîte. – Ani

+0

@Ani: que voulez-vous dire? Par 'T', je fais référence au' typeof (T) ' – thecoop

7

Bien que la réponse de @ theCoop est correct (il n'y a rien de fondamentalement mauvais en plaçant son code dans le corps de la méthode que vous avez fournie), il y a quelques pièges géants ici.

Nullable<T> est traité par l'exécution comme un type 'spécial' qui a une sémantique très particulière. En particulier, lorsqu'un Nullable<T> est encadré:

  1. Si HasValue == true, il se comporte comme une boîte T, rendant impossible pour le code Aval de savoir si l'objet créé a été produit par la boxe un T ou par la boxe un Nullable<T>. Unboxing à T et Nullable<T> sont tous deux possibles. Si HasValue == false, la boxe renvoie simplement null. Unboxing à T va lancer, unboxing à Nullable<T> va réussir, pour lequel HasValue == false.

Dans les deux cas, boxedNullableObject.GetType() ne traduiraient pas que l'objet a été produit par la boxe un Nullable<T>. Je ne peux pas penser à tout autre type de valeur qui présente un tel comportement étrange.

Par exemple, tenez compte:

// Output: "System.Nullable`1[System.Int32]" 
Console.WriteLine(typeof(int?)); 


object boxedNullableInt32WithValue = new int?(0); 

// Output: "System.Int32", NOT "System.Nullable`1[System.Int32]" 
Console.WriteLine(boxedNullableInt32WithValue.GetType()); 


object boxedNullableInt32WithoutValue = new int?(); 

// NullReferenceException is thrown 
Console.WriteLine(boxedNullableInt32WithoutValue.GetType()); 

Par conséquent, l'écriture d'un procédé tel que:

public static bool IsObjectANullableT(this object obj) { ... }

est une très mauvaise idée.

EDIT: Sur une autre note, je viens de réaliser qu'il existe une méthode-cadre qui fait ce que vous avez besoin en utilisant la même technique que @ échantillon de theCoop: Nullable.GetUnderlyingType.

Utilisation:

static bool IsNullable(Type type) 
{ 
    return Nullable.GetUnderlyingType(type) != null; 
} 

EDIT: Je viens de voir que cela aussi a été mentionné par @TheCoop dans sa réponse. Mon erreur.

+0

Points très utiles et importants à mentionner.Heureusement, je cherchais spécifiquement à identifier si la propriété 'PropertyType' d'un' PropertyInfo' était un type nullable; Dans ce cas, la réponse de thecoop fonctionne très bien. Mais vous avez raison de dire que [aucun autre type de valeur ne se comporte de cette façon] (http://stackoverflow.com/questions/3775582/how-is-the-boxing-unboxing-behavior-of-nullablet-possible). –

+0

Haha, c'est génial: vous me dirigez vers une autre question de * votre * qui traite de cette question, sauf avec plus de clarté et de détails. Quel exercice de redondance de ma part. – Ani

+0

Pas du tout! Je ne pense pas que cette réponse soit redondante; il fournit un aperçu très important des pièges potentiels d'une solution générale au problème que j'ai posé dans ma question. J'ai seulement inclus ce lien parce que je pensais qu'il touchait à certains des mêmes problèmes, pour ceux qui cherchent des informations supplémentaires. –