C# 检查类型或实例是否实现IEnumerable,而不考虑类型T
我在当前的项目中做了大量的反思,我试图提供一些帮助方法来保持一切整洁 我想提供一对方法来确定一个类型或实例是否实现了C# 检查类型或实例是否实现IEnumerable,而不考虑类型T,c#,.net,inheritance,reflection,types,C#,.net,Inheritance,Reflection,Types,我在当前的项目中做了大量的反思,我试图提供一些帮助方法来保持一切整洁 我想提供一对方法来确定一个类型或实例是否实现了IEnumerable——而不考虑类型T。以下是我目前的情况: public static bool IsEnumerable(this Type type) { return (type is IEnumerable); } public static bool IsEnumerable(this object obj) { return (obj as IEn
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());
Debug.WriteLine(“类型IEnumerable:+typeof(IEnumerable).IsEnumerable());
WriteLine(“类型IEnumerable:+typeof(IEnumerable).IsEnumerable());
WriteLine(“类型列表:”+typeof(List).IsEnumerable());
WriteLine(“类型字符串:”+typeof(string.IsEnumerable());
WriteLine(“Type DateTime:+typeof(DateTime).IsEnumerable());
WriteLine(“实例列表:+new List().IsEnumerable());
Debug.WriteLine(“实例字符串:“+”.IsEnumerable());
WriteLine(“实例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
类型IEnumerable:False
类型IEnumerable:False
类型列表:False
类型字符串:False
类型DateTime:False
实例列表:True
实例字符串:True
实例日期时间:False
type方法似乎根本不起作用–我希望directSystem.Collections.IEnumerable
至少匹配一个true
我知道string
在技术上是可枚举的,尽管有一些警告。然而,在这种情况下,理想情况下,我需要helper方法为其返回false
。我只需要定义了IEnumerable
类型的实例返回true
我可能刚刚错过了一件相当明显的事情——有人能给我指出正确的方向吗?下面一行
return (type is IEnumerable);
询问“如果类型
的实例,类型
是IEnumerable
”,显然不是
您要做的是:
return typeof(IEnumerable).IsAssignableFrom(type);
除此之外,您还可以使用:
这样,如果您想检查多个接口,可以很容易地修改
实现接口以获得多个接口。要检查某些类型是否实现IEnumerable,而不管T如何,需要检查GenericTypeDefinition
public static bool IsIEnumerableOfT(this Type type)
{
return type.GetInterfaces().Any(x => x.IsGenericType
&& x.GetGenericTypeDefinition() == typeof(IEnumerable<>));
}
公共静态bool IsEnumerableSoft(此类型)
{
返回类型.GetInterfaces().Any(x=>x.IsGenericType
&&x.GetGenericTypeDefinition()==typeof(IEnumerable));
}
我不明白这个问题。很清楚为什么typeof()
任何类型都不会返回true
;您询问的是类型对象是否实现了接口,而不是类型本身。也许您想要IsAssignableFrom()
?但是你认为string
在什么方面不符合条件呢?它确实有一个“已定义的IEnumerable
type”。是的,这就是type one的问题所在——我整天都在看类型和实例之间跳跃的反射嵌套,而且有点困惑<代码>字符串
确实符合条件,但是在本例中,我确实需要排除它-在这个阶段,可能更多的是方法命名的问题。我想我会保持原样,添加另一个只在字符串上键入checks的。同意@jeroenmoster。。。“复制”是询问某个类型是否正在使用反射实现IEnumerable
,这是询问某个类型是否正在实现IEnumerable
,这是另一回事,需要不同的解决方案(不同的公认答案证明了这一点)也许你寻找的是ICollection
而不是IEnumerable
@Octopoid一个字符串实现了IEnumerable
,所以这是真的,因为这就是你要问的for@Octopoid这是正确的行为string
是一个IEnumerable
,它是一个IEnumerable
@Octopoid,如果你再检查一下,它的性能会更好!如果您出于某种原因排除了string
,而没有看到您的代码或了解需求,那么您可能也希望排除许多其他可能的代码(特别是如果您正在制作一个库,可以在将来的代码中使用目前未知的类型)。我不明白为什么string
与许多其他可能的IEnumerable
s不同。如果是这样的话,最好明确说明您支持的内容,而不是使用“implementingIEnumerable
”作为检查,我现在不知道为什么这是公认的answe。IEnumerable与IEnumerable不同,不管T是什么。可以有一些类型只实现IEnumerable。小的修正:在边缘情况下,当type
本身就是typeof(IEnumerable)
时,这会失败,在某些情况下,这会导致无提示的失败:--修复很容易,只需抛出一个.Append(type)
就在该之前。任何
,以便也检查类型本身:
public static bool IsIEnumerableOfT(this Type type)
{
return type.GetInterfaces().Any(x => x.IsGenericType
&& x.GetGenericTypeDefinition() == typeof(IEnumerable<>));
}