如何确定对象的类型是否为IEnumerable< T>?
代码:
namespace NS {
class Program {
static IEnumerable<int> GetInts() {
yield return 1;
}
static void Main() {
var i = GetInts();
var type = i.GetType();
Console.WriteLine(type.ToString());
}
}
}
输出:
NS.1.Program+<GetInts>d__0
如果我更改GetInts以返回IList,一切正常 输出是:
System.Collections.Generic.List`1[System.Int32]
这会返回false:
namespace NS {
class Program {
static IEnumerable<int> GetInts() {
yield return 1;
}
static void Main() {
var i = GetInts();
var type = i.GetType();
Console.WriteLine(type.Equals(typeof(IEnumerable<int>)));
}
}
}
答案 0 :(得分:99)
如果您指的是集合,那么只需as
:
var asEnumerable = i as IEnumerable<int>;
if(asEnumerable != null) { ... }
但是,我假设(从示例中)您有Type
:
对象永远不会是“{”类型IEnumerable<int>
- 但它可能实现它;我希望如此:
if(typeof(IEnumerable<int>).IsAssignableFrom(type)) {...}
会这样做。如果你不知道T
(上面的int
),那么检查所有已实现的接口:
static Type GetEnumerableType(Type type) {
foreach (Type intType in type.GetInterfaces()) {
if (intType.IsGenericType
&& intType.GetGenericTypeDefinition() == typeof(IEnumerable<>)) {
return intType.GetGenericArguments()[0];
}
}
return null;
}
并致电:
Type t = GetEnumerableType(type);
如果为空,则IEnumerable<T>
不是T
- 否则请检查t
。
答案 1 :(得分:14)
与Marc的答案相同,但Linqier:
namespace NS
{
class Program
{
static IEnumerable<int> GetInts()
{
yield return 1;
}
static void Main()
{
var i = GetInts();
var type = i.GetType();
var isEnumerableOfT = type.GetInterfaces()
.Any(ti => ti.IsGenericType
&& ti.GetGenericTypeDefinition() == typeof(IEnumerable<>));
Console.WriteLine(isEnumerableOfT);
}
}
}
答案 2 :(得分:14)
因为IEnumerable&lt; T&gt;继承IEnumerable(非泛型),如果你不需要知道何时类型只是IEnumerable而不是IEnumerable&lt; T&gt;然后你可以使用:
if (typeof(IEnumerable).IsAssignableFrom(srcType))
答案 3 :(得分:7)
如何确定对象是否属于类型 IEnumerable&lt; T&gt;?
请随意使用这个精细的,超小的通用扩展方法来确定是否有任何对象实现IEnumerable接口。它扩展了 Object 类型,因此您可以使用您正在使用的任何对象的任何实例来执行它。
public static class CollectionTestClass
{
public static Boolean IsEnumerable<T>(this Object testedObject)
{
return (testedObject is IEnumerable<T>);
}
}
答案 4 :(得分:3)
i
属于NS.1.Program+<GetInts>d__0
类型,是IEnumerable<int>
的子类型。因此,您可以使用
if (i is IEnumerable<int>) { ... }
或IsAssignableFrom
(就像Marc的回答一样)。
答案 5 :(得分:1)
您可以使用is
关键字。
[TestFixture]
class Program
{
static IEnumerable<int> GetInts()
{
yield return 1;
}
[Test]
static void Maasd()
{
var i = GetInts();
Assert.IsTrue(i is IEnumerable<int>);
}
}
答案 6 :(得分:0)
How to detect if type is another generic type可以帮助您解决这个问题。
答案 7 :(得分:0)
尝试
type.GetInterface(“ IEnumerable”)!= null && type.IsGenericType
答案 8 :(得分:0)
我相信解决此问题的最佳方法应该很简单。您首先编写返回IEnumerable<T>
的通用参数(或您情况下的参数)的代码,然后编写另一行以对参数进行比较您希望与IEnumerable<T>
对象中包含的类型进行比较的类型(在您的情况下为int
)。我有一个示例,其中显示了处理两个任务的两个简单函数。
public static Type GetEnumerableArgumentType(Type type)
{
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
return type.GetGenericArguments()[0];
else
return null;
}
public static bool EnumerableContainsArgumentType(Type tEnumerable, Type tGenArg)
{
return GetEnumerableArgumentType(tEnumerable) == tGenArg;
}
答案 9 :(得分:0)
对于那些只想知道如何从IEnumerable或从IEnumerable返回true或false的人,我使用了Marcs原始答案来创建我现在正在使用的这种通用方法。
private static bool ImplementsIEnumerable<T>(T obj)
{
var type = obj.GetType();
if (type.IsInterface && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
{
return true;
}
foreach (Type interfaceUsed in type.GetInterfaces())
{
if (interfaceUsed.IsGenericType
&& interfaceUsed.GetGenericTypeDefinition() == typeof(IEnumerable<>))
{
return true;
}
}
return false;
}