222 votes

Comment vérifier si un objet est nullable ?

Comment puis-je vérifier si un objet donné est nullable en d'autres termes la façon de mettre en œuvre la méthode suivante...

bool IsNullableValueType(object o)
{
    ...
}

EDIT: je suis à la recherche d'nullable types de valeur. Je n'ai pas de ref types à l'esprit.

//Note: This is just a sample. The code has been simplified 
//to fit in a post.

public class BoolContainer
{
	bool? myBool = true;
}

var bc = new BoolContainer();

const BindingFlags bindingFlags = BindingFlags.Public
						| BindingFlags.NonPublic
						| BindingFlags.Instance
						;


object obj;
object o = (object)bc;

foreach (var fieldInfo in o.GetType().GetFields(bindingFlags))
{
	obj = (object)fieldInfo.GetValue(o);
}

obj fait maintenant référence à un objet de type bool (System.Boolean) avec une valeur égale à true. Ce que je voulais, c'était un objet de type Nullable<bool>

Alors maintenant, comme j'ai décidé de vérifier si o est nullable et de créer un nullable wrapper autour de l'obj.

296voto

Marc Gravell Points 482669

Il existe deux types de nullable - Nullable<T> et de référence-type.

Jon a corrigé moi qu'il est difficile d'obtenir le type s'en boîte, mais vous pouvez les génériques: - alors, comment ci-dessous. C'est en fait les essais de type T, mais à l'aide de l' obj paramètre purement pour l'inférence de type générique (pour le rendre facile d'appel) - il serait de travailler presque à l'identique sans l' obj param.

static bool IsNullable<T>(T obj)
{
    if (obj == null) return true; // obvious
    Type type = typeof(T);
    if (!type.IsValueType) return true; // ref-type
    if (Nullable.GetUnderlyingType(type) != null) return true; // Nullable<T>
    return false; // value-type
}

Mais cela ne fonctionne pas tellement bien si vous avez déjà encadré de la valeur à une variable objet.

47voto

Dean Chalk Points 7935

Il existe une solution très simple à l’aide de surcharges de méthode

http://www.deanchalk.me.uk/post/is-it-Nullable-.aspx

extrait :

puis

29voto

Allon Guralnek Points 8545

La question de "Comment faire pour vérifier si un type est nullable?", "Comment faire pour vérifier si un type est Nullable<>?", qui peut être généralisée à "Comment faire pour vérifier si un type est un type construit de certains type générique?", de sorte qu'il ne répond pas seulement à la question "Est - Nullable<int> un Nullable<>?", mais aussi "Est - List<int> un List<>?".

La plupart de la solution fournie par l'utilisation de l' Nullable.GetUnderlyingType() méthode, qui sera bien évidemment qu'avec le cas de l' Nullable<>. Je n'ai pas vu le général réfléchissant solution qui fonctionne avec n'importe quel type générique, j'ai donc décidé de l'ajouter ici, pour la postérité, même si cette question a déjà été répondu il y a longtemps.

Pour vérifier si un type est une forme d' Nullable<> en utilisant la réflexion, vous devez d'abord convertir vos construits de type générique, par exemple Nullable<int>, dans le générique de la définition de type, Nullable<>. Vous pouvez le faire en utilisant l' GetGenericTypeDefinition() méthode de Type classe. Vous pouvez alors comparer le type résultant d' Nullable<>:

Type typeToTest = typeof(Nullable<int>);
bool isNullable = typeToTest.GetGenericTypeDefinition() == typeof(Nullable<>);
// isNullable == true

La même chose peut être appliquée à tout type générique:

Type typeToTest = typeof(List<int>);
bool isList = typeToTest.GetGenericTypeDefinition() == typeof(List<>);
// isList == true

Plusieurs types peuvent sembler identiques, mais un nombre différent d'arguments de type signifie que c'est un genre complètement différent.

Type typeToTest = typeof(Action<DateTime, float>);
bool isAction1 = typeToTest.GetGenericTypeDefinition() == typeof(Action<>);
bool isAction2 = typeToTest.GetGenericTypeDefinition() == typeof(Action<,>);
bool isAction3 = typeToTest.GetGenericTypeDefinition() == typeof(Action<,,>);
// isAction1 == false
// isAction2 == true
// isAction3 == false

Depuis Type objet instancié qu'une seule fois par type, vous pouvez vérifier pour la référence à l'égalité entre eux. Donc, si vous voulez vérifier si deux objets sont de la même générique de la définition de type, vous pouvez écrire:

var listOfInts = new List<int>();
var listOfStrings = new List<string>();

bool areSameGenericType =
    listOfInts.GetType().GetGenericTypeDefinition() ==
    listOfStrings.GetType().GetGenericTypeDefinition();
// areSameGenericType == true

Si vous souhaitez vérifier si un objet est nullable, plutôt que d'un Type, alors vous pouvez utiliser la technique décrite ci-dessus en collaboration avec Marc Gravel est la solution pour créer une plutôt une méthode simple:

static bool IsNullable<T>(T obj)
{
    if (!typeof(T).IsGenericType)
        return false;

    return typeof(T).GetGenericTypeDefinition() == typeof(Nullable<>);
}

20voto

Jon Skeet Points 692016

Eh bien, vous pouvez utiliser :

... mais l’objet lui-même n’est pas nullable ou autrement - est un type . Comment aviez vous prévu l’utilisation de ce ?

11voto

Carlos Loth Points 2083

Je peux comprendre le moyen le plus simple est :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X