【问题标题】:How to check if type is IEnumerable<BaseType>?如何检查类型是否为 IEnumerable<BaseType>?
【发布时间】:2010-09-26 12:34:02
【问题描述】:

应该很容易...

class Base{}    
class Foo:Base{}

public bool Bar(Type t){
  // return ???
  // NB: shouldn't know anything about Foo, just Base
}

Assert.True(Bar(typeof(IEnumerable<Foo>));
Assert.False(Bar(typeof(IEnumerable<Base>));
Assert.False(Bar(typeof(string));
Assert.False(Bar(typeof(Foo));

只是为了回答为什么第二个应该是错误的问题(实际上 - 没关系,因为 Bar 参数永远不会是 IEnumerable&lt;Base&gt;)。

我正在尝试编写 FluentNhibernate 自动映射约定,它将我的类枚举映射到整数。我已经成功地做到了,但是当我想映射 IEnumerable&lt;EnumerationChild&gt;(在我的例子中是 User.Roles)时事情就失败了。

public class EnumerationConvention:IUserTypeConvention{
    private static readonly Type OpenType=typeof(EnumerationType<>);
    public void Apply(IPropertyInstance instance){
      //this is borked atm, must implement ienumerable case
      var closedType=OpenType.MakeGenericType(instance.Property.PropertyType);
      instance.CustomType(closedType);
    }
    public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria){
      criteria.Expect(
        x=>typeof(Enumeration).IsAssignableFrom(x.Property.PropertyType) ||  
           typeof(IEnumerable<Enumeration>)
             .IsAssignableFrom(x.Property.PropertyType));
    }
  }

【问题讨论】:

  • 你真的不能想出一个比Bar更好的函数名吗?
  • @Timwi Baz 怎么样?
  • @Arnis:你见过多少段代码有这样的函数名?你真的想不出一个描述函数的名字吗?
  • @Timwi 我不确定您要达到的目标。我认为在提问时使用元句法变量是个好主意。想法是强迫人们理解代码的结构而不是它的目的。如果我明确询问有关 FNH 自动映射和类枚举器的问题 - 我会等待数周才能得到答案。
  • @Arnis:该功能与 FNH 自动映射无关。您的问题是“对于派生自Base 的某些T,如何确定类型t 是否为IEnumerable&lt;T&gt;”。当然,调用类似IsIEnumerableBaseDerived 或类似的函数比Bar 清晰一百万倍。

标签: c# c#-4.0 types ienumerable


【解决方案1】:

您可以使用Type.IsAssignableFrom(Type)。但是,您的问题不是很清楚 - 您指定 一个 类型,但您需要两个...Bar 是要检查 t 反对的类型?

请注意,由于通用协方差,答案将在 .NET 3.5 和 .NET 4 之间发生变化 - 例如,在 .NET 3.5 中,List&lt;Foo&gt;不能分配给 IEnumerable&lt;Base&gt;,但在 .NET 4 中是这样。

编辑:这是一个打印 True、True、False、False 的程序。我不确定你为什么认为第二个是假的:

using System;
using System.Collections;
using System.Collections.Generic;

class Base{}    
class Foo:Base{}

class Test
{
    static bool Bar(Type t)
    {
        return typeof(IEnumerable<Base>).IsAssignableFrom(t);
    }

    static void Main()
    {
        Console.WriteLine(Bar(typeof(IEnumerable<Foo>)));
        Console.WriteLine(Bar(typeof(IEnumerable<Base>)));
        Console.WriteLine(Bar(typeof(string)));
        Console.WriteLine(Bar(typeof(Foo)));
    }
}

【讨论】:

  • 如果参数是typeof(Foo),这将起作用。但据我所知 - 如果参数是 typeof(IEnumerable&lt;Foo&gt;),它不会。
  • @Arnis:查看我的编辑 - 您使用的是 .NET 3.5 还是 .NET 4?另请注意我的编辑,我询问您正在检查哪些 two 类型。您尚未指定应根据 IEnumerable&lt;T&gt; 检查哪种类型。
  • 这里使用 c# 4。标记的问题。
  • 如果参数是派生自 Base 的类型的 IEnumerable,我需要 Bar 返回 true。
  • @Arnis:那为什么你的第二个断言是错误的?您不想将IEnumerable&lt;Base&gt; 本身算作实现IEnumerable&lt;Base&gt;
猜你喜欢
  • 2011-09-07
  • 2012-09-20
  • 2015-06-25
  • 1970-01-01
  • 1970-01-01
  • 2016-05-01
  • 1970-01-01
  • 2017-10-28
  • 1970-01-01
相关资源
最近更新 更多