【问题标题】:How to know if a PropertyInfo is a collection如何知道 PropertyInfo 是否是一个集合
【发布时间】:2010-08-25 20:08:06
【问题描述】:

以下是我用来获取类中所有公共属性的初始状态以进行 IsDirty 检查的一些代码。

查看属性是否为 IEnumerable 的最简单方法是什么?

干杯,
浆果

  protected virtual Dictionary<string, object> _GetPropertyValues()
    {
        return _getPublicPropertiesWithSetters()
            .ToDictionary(pi => pi.Name, pi => pi.GetValue(this, null));
    }

    private IEnumerable<PropertyInfo> _getPublicPropertiesWithSetters()
    {
        return GetType().GetProperties().Where(pi => pi.CanWrite);
    }

更新

我最终做的是添加一些库扩展,如下所示

    public static bool IsNonStringEnumerable(this PropertyInfo pi) {
        return pi != null && pi.PropertyType.IsNonStringEnumerable();
    }

    public static bool IsNonStringEnumerable(this object instance) {
        return instance != null && instance.GetType().IsNonStringEnumerable();
    }

    public static bool IsNonStringEnumerable(this Type type) {
        if (type == null || type == typeof(string))
            return false;
        return typeof(IEnumerable).IsAssignableFrom(type);
    }

【问题讨论】:

    标签: c# reflection


    【解决方案1】:
    if (typeof(IEnumerable).IsAssignableFrom(prop.PropertyType) && prop.PropertyType != typeof(string))
    

    【讨论】:

    • 请注意,字符串也是 IEnumerable
    • 更好:p.PropertyType != typeof(string) && typeof(IEnumerable).IsAssignableFrom(p.PropertyType)
    【解决方案2】:

    我同意 Fyodor Soikin 的观点,但 Enumerable 的事实并不意味着它只是一个 Collection,因为字符串也是 Enumerable 并且一个一个地返回字符...

    所以我建议使用

    if (typeof(ICollection<>).IsAssignableFrom(pi.PropertyType))
    

    【讨论】:

    • 你对字符串当然是正确的,但你的解决方案失败了(用 List() 试试)。有关我最终使用的代码,请参阅我的更新。干杯!
    • 这会失败,因为没有构造类型(如List&lt;string&gt;)可以分配给泛型类型(ICollection&lt;&gt;)(实际上,您不能声明ICollection&lt;&gt; 类型的变量)。所以最好使用typeof(ICollection)(如编辑建议的那样),这也将使其适用于非泛型集合。
    • 确实非常好
    【解决方案3】:

    试试

    private bool IsEnumerable(PropertyInfo pi)
    {
       return pi.PropertyType.IsSubclassOf(typeof(IEnumerable));
    }
    

    【讨论】:

    • 我最近注意到如果 x == y,x.IsSubClassOf(y) 将返回 false。在这种情况下,如果属性恰好是 IEnumerable 类型,那么函数将返回 false。
    • 这很有趣,老实说,我从来没有在这个确切的上下文中真正使用过这个逻辑,所以我很高兴你指出了这一点。谢谢。
    猜你喜欢
    • 2010-12-06
    • 2015-02-14
    • 2014-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-26
    • 1970-01-01
    相关资源
    最近更新 更多