如何确定一个对象是否实现了任何类型的IDictionary或IList

5
假设我声明了以下内容:
Dictionary<string, string> strings = new Dictionary<string, string>();
List<string> moreStrings = new List<string>();

public void DoSomething(object item)
{
   //here i need to know if item is IDictionary of any type or IList of any type.
}

我尝试使用了以下方法:
item is IDictionary<object, object>
item is IDictionary<dynamic, dynamic>

item.GetType().IsAssignableFrom(typeof(IDictionary<object, object>))
item.GetType().IsAssignableFrom(typeof(IDictionary<dynamic, dynamic>))

item is IList<object>
item is IList<dynamic>

item.GetType().IsAssignableFrom(typeof(IList<object>))
item.GetType().IsAssignableFrom(typeof(IList<dynamic>))

所有这些都返回false!

那么在这种情况下,我如何确定项目是否实现了IDictionary或IList?


@DaveZych,那么我该如何检测该项是否使用了任何泛型类型实现IDictionary或IList? - Matthew Layton
你正在错误地使用 IsAssignableFrom。这是正确的用法:typeof(Dictionary<string, string>).IsAssignableFrom(new Dictionary<string, string>().GetType()); - khellang
我可以问一下使用场景吗? - paparazzo
4个回答

9
    private void CheckType(object o)
    {
        if (o is IDictionary)
        {
            Debug.WriteLine("I implement IDictionary");
        }
        else if (o is IList)
        {
            Debug.WriteLine("I implement IList");
        }
    }

1
它不起作用:new ExpandoObject()是IDictionary返回false,他问它是否实现了IDictionary<,>的任何实现。 - elios264
@elios264,你可以尝试使用IDictionary<string, dynamic>和IList<dynamic>进行检查。 - Andy

4

您可以使用非泛型接口类型,或者如果您确实需要知道该集合是泛型的,可以使用没有类型参数的 typeof

obj.GetType().GetGenericTypeDefinition() == typeof(IList<>)
obj.GetType().GetGenericTypeDefinition() == typeof(IDictionary<,>)

为了保险起见,您应该检查 obj.GetType().IsGenericType 以避免针对非泛型类型的 InvalidOperationException


item.GetType() == typeof(IList<>) 仍然为 false,请尝试这样做。 - cuongle
如果对象是值类型,比如 int/string,那么这会出错,因为它们没有实现 GetGenericTypeDefinition() 方法。 - dragos
@dragos 如果按照检查“IsGenericType”的答案中的指导进行操作,就不会出现这种情况。 - Jay

1

不确定这是否符合您的要求,但您可以在项目类型上使用GetInterfaces,然后查看返回列表中是否有任何IDictionaryIList

item.GetType().GetInterfaces().Any(x => x.Name == "IDictionary" || x.Name == "IList")

我想那应该可以了。


0

以下是一些在vb.net框架2.0中与通用接口类型一起使用的布尔函数:

Public Shared Function isList(o as Object) as Boolean
    if o is Nothing then return False
    Dim t as Type = o.GetType()
    if not t.isGenericType then return False
    return (t.GetGenericTypeDefinition().toString() = "System.Collections.Generic.List`1[T]")
End Function

Public Shared Function isDict(o as Object) as Boolean
    if o is Nothing then return False
    Dim t as Type = o.GetType()
    if not t.isGenericType then return False
    return (t.GetGenericTypeDefinition().toString() = "System.Collections.Generic.Dictionary`2[TKey,TValue]")
End Function

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接