web-dev-qa-db-fra.com

Vérifier si l'objet est un dictionnaire ou une liste

En travaillant avec .NET 2 en mono, j'utilise une bibliothèque JSON de base qui retourne une chaîne imbriquée, un dictionnaire d'objets et des listes.

J'écris un mappeur pour mapper ceci à une classe jsonData que j'ai déjà et je dois pouvoir déterminer si le type sous-jacent d'une object est un dictionnaire ou une liste. Ci-dessous, la méthode que j’utilise pour effectuer ce test, mais je me demandais s’il y avait une méthode plus propre?

private static bool IsDictionary(object o) {
    try {
        Dictionary<string, object> dict = (Dictionary<string, object>)o;
        return true;
    } catch {
        return false;
    }
}

private static bool IsList(object o) {
    try {
        List<object> list = (List<object>)o;
        return true;
    } catch {
        return false;
    }
}

La bibliothèque que j'utilise est litJson mais la classe JsonMapper ne fonctionne essentiellement pas sur iOS, d'où la raison pour laquelle j'écris mon propre mappeur.

13
user1711383

Utilisez le mot clé is et la réflexion.

public bool IsList(object o)
{
    if(o == null) return false;
    return o is IList &&
           o.GetType().IsGenericType &&
           o.GetType().GetGenericTypeDefinition().IsAssignableFrom(typeof(List<>));
}

public bool IsDictionary(object o)
{
    if(o == null) return false;
    return o is IDictionary &&
           o.GetType().IsGenericType &&
           o.GetType().GetGenericTypeDefinition().IsAssignableFrom(typeof(Dictionary<,>));
}
28
Romoku

Si vous voulez vérifier qu'un certain objet est d'un type, utilisez l'opérateur is. Par exemple:

private static bool IsDictionary(object o)
{
    return o is Dictionary<string, object>;
}

Bien que pour quelque chose d'aussi simple, vous n'avez probablement pas besoin d'une méthode séparée, utilisez simplement l'opérateur is directement où vous en avez besoin.

3
svick

Modifier la réponse ci-dessus. Pour utiliser GetGenericTypeDefinition(), vous devez précéder la méthode avec GetType(). Si vous regardez MSDN, voici comment accéder à GetGenericTypeDefinition()

public virtual Type GetGenericTypeDefinition()

Voici le lien: https://msdn.Microsoft.com/en-us/library/system.type.getgenerictypedefinition(v=vs.110).aspx

public bool IsList(object o)
{
    return o is IList &&
       o.GetType().IsGenericType &&
       o.GetType().GetGenericTypeDefinition().IsAssignableFrom(typeof(List<>));
}

public bool IsDictionary(object o)
{
    return o is IDictionary &&
       o.GetType().IsGenericType &&
       o.GetType().GetGenericTypeDefinition().IsAssignableFrom(typeof(Dictionary<>));
}
2
TheMiddleMan

Si vous avez juste besoin de détecter que l'objet est List/Dictionary ou non, vous pouvez utiliser myObject.GetType().IsGenericType && myObject is IEnumerable

Voici quelques exemples:

var lst = new List<string>();
var dic = new Dictionary<int, int>();
string s = "Hello!";
object obj1 = new { Id = 10 };
object obj2 = null;

// True
Console.Write(lst.GetType().IsGenericType && lst is IEnumerable);
// True
Console.Write(dic.GetType().IsGenericType && dic is IEnumerable);
// False
Console.Write(s.GetType().IsGenericType && s is IEnumerable);
// False
Console.Write(obj1.GetType().IsGenericType && obj1 is IEnumerable);
// NullReferenceException: Object reference not set to an instance of 
// an object, so you need to check for null cases too
Console.Write(obj2.GetType().IsGenericType && obj2 is IEnumerable);
0
Mehdi Dehghani