检查 Type 或实例是否实现 IEnumerable 而不管类型 T

Checking if Type or instance implements IEnumerable regardless of Type T

我正在对我当前的项目进行大量反思,我正在尝试提供一些辅助方法以保持一切整洁。

我想提供一对方法来确定类型或实例是否实现 IEnumerable – 无论类型 T。这是我目前拥有的:

public static bool IsEnumerable(this Type type)
{
    return (type is IEnumerable);
}

public static bool IsEnumerable(this object obj)
{
    return (obj as IEnumerable != null);
}

当我使用

测试它们时
Debug.WriteLine("Type IEnumerable:   " + typeof(IEnumerable).IsEnumerable());
Debug.WriteLine("Type IEnumerable<>: " + typeof(IEnumerable<string>).IsEnumerable());
Debug.WriteLine("Type List:          " + typeof(List<string>).IsEnumerable());
Debug.WriteLine("Type string:        " + typeof(string).IsEnumerable());
Debug.WriteLine("Type DateTime:      " + typeof(DateTime).IsEnumerable());
Debug.WriteLine("Instance List:      " + new List<string>().IsEnumerable());
Debug.WriteLine("Instance string:    " + "".IsEnumerable());
Debug.WriteLine("Instance DateTime:  " + new DateTime().IsEnumerable());

我得到的结果是:

Type IEnumerable:   False
Type IEnumerable<>: False
Type List:          False
Type string:        False
Type DateTime:      False
Instance List:      True
Instance string:    True
Instance DateTime:  False

类型方法似乎根本不起作用——我原以为至少 System.Collections.IEnumerable 直接匹配 true

我知道 string 在技术上是可枚举的,尽管有一些警告。然而,在这种情况下,理想情况下,我需要 return false 的辅助方法。我只需要 IEnumerable<T> 类型定义为 return true.

的实例

我可能只是错过了一些相当明显的东西 – 谁能指出我正确的方向?

下面一行

return (type is IEnumerable);

在问"if an instance of Type, type is IEnumerable",显然不是。

您要做的是:

return typeof(IEnumerable).IsAssignableFrom(type);

除了Type.IsAssignableFrom(Type), you can also use Type.GetInterfaces()

public static bool ImplementsInterface(this Type type, Type interfaceType)
{
    // Deal with the edge case
    if ( type == interfaceType)
        return true;

    bool implemented = type.GetInterfaces().Contains(interfaceType);
    return implemented;
}

这样,如果您想检查多个接口,您可以轻松修改 ImplementsInterface 以采用多个接口。

要检查某种类型是否实现了 IEnumerable 不管 T 需要检查 GenericTypeDefinition。

public static bool IsIEnumerableOfT(this Type type)
{
    return type.GetInterfaces().Any(x => x.IsGenericType
           && x.GetGenericTypeDefinition() == typeof(IEnumerable<>));
}