2013-06-19 3 views
11

Работа с .NET 2 в моно, я использую базовую библиотеку JSON, которая возвращает вложенную строку, словарь и списки объектов.Проверьте, является ли Object словарем или списком

Я пишу картограф, чтобы сопоставить это с классом jsonData, который у меня уже есть, и мне нужно определить, является ли базовый тип object словарем или списком. Ниже приведен метод, который я использую для выполнения этого теста, но задавался вопросом, есть ли более чистый способ?

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; 
    } 
} 

Библиотеки я использую litJson но JsonMapper класса по существу не работает на IOS, следовательно, почему я пишу свой собственный картограф.

ответ

20

Используйте ключевое слово и отражение is.

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<,>)); 
} 
+0

System.Type оленья кожа себе em, чтобы быть доступным мне в моно, и поэтому использовать GetGenericTypeDefinition .. это бит нужен? – user1711383

+1

Похоже, что типы всегда 'List ' и 'Dictionary ', поэтому вам не нужно все это отражение. – svick

+0

o может быть строкой, int, long, bool, double, List или Dictionary – user1711383

2

Если вы хотите проверить, что определенный объект некоторого типа, используйте оператор is. Например:

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

Хотя для чего-то это просто, вы, вероятно, не нужен отдельный метод, просто использовать оператор is непосредственно там, где вам это нужно.

+0

Осторожно - оператор 'is' проверяет, является ли объект левой руки СОВМЕСТИМЫ с объектом правой руки, НЕ, если какой-либо объект обязательно является тем же самым type ... – Ben

+0

@Ben Да, но если тип 'o' наследует от словаря ', я думаю, что 'true' - правильный ответ здесь. – svick

2

Изменение вышеуказанного ответа. Для использования GetGenericTypeDefinition() вы должны ввести метод GetType(). Если вы посмотрите на MSDN это как GetGenericTypeDefinition() доступ:

public virtual Type GetGenericTypeDefinition() 

Вот ссылка: 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<>)); 
} 
0

Если вам просто нужно определить объект List/Dictionary или нет, вы можете использовать myObject.GetType().IsGenericType && myObject is IEnumerable

Вот несколько примеров:

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);