使用泛型时如何比较类型?

时间:2009-07-29 17:11:19

标签: c# generics reflection c#-2.0

我试图在运行时派生一个对象的类型。具体来说,我需要知道它是否实现ICollection或IDto两件事。目前我唯一能找到的解决方案是:

   private static bool IsACollection(PropertyDescriptor descriptor)
    {
        bool isCollection = false;

        foreach (Type type in descriptor.PropertyType.GetInterfaces())
        {
            if (type.IsGenericType)
            {
                if (type.GetGenericTypeDefinition() == typeof(ICollection<>))
                {
                    isCollection = true;
                    break;
                }
            }
            else
            {
                if (type == typeof(ICollection))
                {
                    isCollection = true;
                    break;
                }
            }
        }


        return isCollection;
    }

    private static bool IsADto(PropertyDescriptor descriptor)
    {
        bool isDto = false;

        foreach (Type type in descriptor.PropertyType.GetInterfaces())
        {
            if (type == typeof(IDto))
            {
                isDto = true;
                break;
            }
        }          
        return isDto;
    }

然而,我确信必须有一个比这更好的方法。我尝试过以正常方式进行比较,例如:

if(descriptor.PropertyType == typeof(ICollection<>))

然而,当使用反射但未使用反射时它会失败,它可以正常工作。

我不想为我的实体的每个字段迭代接口。有人可以解释另一种方法吗?是的,我过早地进行了优化,但它看起来也很难看,所以请幽默我。

注意事项:

  1. 它可能是也可能不是通用的,例如IList&lt;&gt;或者只是ArrayList因此我寻找ICollection或ICollection&lt;&gt;。所以我假设我应该在if语句中使用IsGenericType来知道是否使用ICollection&lt;&gt;进行测试或不。
  2. 提前致谢!

2 个答案:

答案 0 :(得分:11)

此:

type == typeof(ICollection)

将检查属性类型是否完全 ICollection。也就是说,它将返回true:

public ICollection<int> x { get; set; }

但不适用于:

public List<int> x { get; set; }

如果您想检查属性的类型是,还是来自ICollection,最简单的方法是使用Type.IsAssignableFrom

typeof(ICollection).IsAssignableFrom(type)

同样适用于通用:

typeof(ICollection<>).IsAssignableFrom(type.GetGenericTypeDefinition())

答案 1 :(得分:2)

type.IsAssignable在这种情况下有帮助吗?

编辑:抱歉,应该是Type.IsAssignableFrom