【问题标题】:Get all ObservableCollection<T> properties of an object based on base type根据基类型获取对象的所有 ObservableCollection<T> 属性
【发布时间】:2014-11-11 20:31:03
【问题描述】:

我正在尝试使用反射获取对象的所有 ObservableCollection 属性。 例如我有一个 Person 类,它具有 ObservableCollection 和 ObservableCollection,PhoneModel 和 AddressModel 都继承自 ModelBaseclass。现在我有以下函数试图选择所有 ObservableCollection 属性。

/// <summary>
/// Get all the oversablecollection properties from the object
/// </summary>
/// <typeparam name="T">type to search for</typeparam>
/// <param name="model">object to return properties for</param>
public IList<ObservableCollection<T>> GetObservableCollections<T>(object model)
{
    var type = model.GetType();
    var result = new List<ObservableCollection<T>>();
    foreach (var prop in type.GetProperties())
    {
        if (prop.PropertyType.IsAssignableFrom(typeof(ObservableCollection<T>)))
        {
            var get = prop.GetGetMethod();
            if (!get.IsStatic && get.GetParameters().Length == 0) // skip indexed & static
            {
                var collection = (ObservableCollection<T>)get.Invoke(model, null);
                if (collection != null) 
                    result.Add(collection);
            }
        }
    }

    return result;
}

这行得通:

[TestMethod]
public void GetObservableCollections_HasOnePublicProperty_Return1()
{
    var personWithPhones = GetValidPersonAndPhonesModel();
    var collection = GetObservableCollections<PhoneModel>(personWithPhones);

    Assert.IsTrue(collection.Count()==1);
}

我希望它能够正常工作,例如,不是针对特定模型而是针对 ModelBase 查找,例如,我希望所有 ObservableCollectionProperties 都用于地址和电话

[TestMethod]
public void GetObservableCollections_HasOnePublicProperty_Return1()
{
    var personWithPhones = GetValidPersonAndPhonesModel();
    var collection = GetObservableCollections<ModelBase>(personWithPhones);

    Assert.IsTrue(collection.Count()==2);
}

上面没有返回任何东西。

有什么建议吗?

===> 这是彼得建议后的更新代码,但有一些转换错误:

            public static IList<ObservableCollection<T>> GetObservableCollections<T>(object obj)
    {
        var type = obj.GetType();

        IList<object> list = new List<object>();
        IList<ObservableCollection<T>> result = new List<ObservableCollection<T>>();
        foreach (var prop in type.GetProperties().Where(p=> p.PropertyType.IsGenericType))
        {
            var unclosedTyped = prop.PropertyType.GetGenericTypeDefinition();
            if (unclosedTyped == typeof(ObservableCollection<>))
            {
                // you have an ObservableCollection<> property
                var elementType = prop.PropertyType.GetGenericArguments().First();
                if (typeof(ModelBase).IsAssignableFrom(elementType))
                {
                    // you have indeed an ObservableCollection property 
                    // with elements that inherit `ModelBase`
                    var get = prop.GetGetMethod();
                    if (!get.IsStatic && get.GetParameters().Length == 0) // skip indexed & static
                    {
                        var collection = get.Invoke(obj, null);
                        if (collection != null)
                        {
                            //list.Add(collection); // This works
                            result.Add((ObservableCollection<T>) collection);
                        }
                    }
                }
            }
        }

        return list;
}

【问题讨论】:

    标签: c# reflection properties observablecollection


    【解决方案1】:

    您可以查找ObservableCollection&lt;&gt;unclosed 类型,而不是查看closed 泛型类型。像这样的:

    var unclosedTyped = prop.PropertyType.GetGenericTypeDefinition();
    if (unclosedTyped == typeof(ObservableCollection<>))
    {
        // you have an ObservableCollection<> property
    }
    

    进一步检查集合元素类型:

    var elementType = prop.PropertyType.GetGenericArguments().First();
    if (typeof(ModelBase).IsAssignableFrom(elementType))
    {
       // you have indeed an ObservableCollection property 
       // with elements that inherit `ModelBase`
    }
    

    【讨论】:

    • 嗨彼得,感谢您的回复。这似乎正在解决该问题,但是当我尝试将道具强制转换为 ObservableCollection 时,我得到了一个 InvalidCastException,例如这一行 -> var collection = (ObservableCollection)get.Invoke(model, null); .....我只是想知道这种方法会起作用吗?
    • 嗯,您使用的是 .NET 3.5 吗?看看这个线程:stackoverflow.com/questions/1198751/…
    • 不,我在 .Net 4.5 中。 ....我可以转换为可以正常工作的对象...但我不希望我猜...
    猜你喜欢
    • 1970-01-01
    • 2021-03-18
    • 1970-01-01
    • 1970-01-01
    • 2011-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多