在不知道泛型类型的情况下注册到ObservableCollection <anytype> .CollectionChanged?

时间:2018-05-01 08:39:20

标签: c# .net generics reflection

我有一个“基础”课程,我希望观察所做的任何改动。

对于所有属性,我会浏览stageGetValue<T>()。然后我有一个SetValue<T>()的支持字段,以Dictionary作为密钥存储。

执行CallerMemberName时,如果SetValue<T>()T注册到ObservableCollection<AnyThing>事件(或取消注册之前的值),我希望如此。

知道如何实现这个目标吗?

CollectionChanged

目标是在每次插入/删除

时创建一个对象
public void RegisterIfObservable<T>(T value){
    Type type = typeof(T);
    if(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ObservableCollection<>)){
        //TODO Register
    }   
}

2 个答案:

答案 0 :(得分:1)

CollectionChanged事件可通过ObservableCollection<T>实现的接口INotifyCollectionChanged获得。您可以使用它,并使用Type删除所有检查。

答案 1 :(得分:0)

你可以有一个帮助方法public void RegisterObservable<T>(IObservable<T> value) {},你可以通过反射调用它:

public void RegisterIfObservable<T>(T value){
    Type type = value.GetType(); 
    // I don't think you can simply use typeof(T) instead of value.GetType() here
    // if the compiler does not know for certain at compile time 
    // whether T will be an IObservable. 
    // And if you DO know that at compile time, then use the alternative solution below.

    if(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ObservableCollection<>))
    {
        Type genericArgument = type.GetGenericArguments()[0];
        MethodInfo method = this.GetType().GetMethod("RegisterObservable"); 
        // instead of this.GetType() you could use the type
        // of a helper class where RegisterObservable is located

        MethodInfo genericMethod = method.MakeGenericMethod(genericArgument);
        genericMethod.Invoke(this, new object[]{value});
    }
}

每次都会涉及很多反思,Mattis解决方案可能更快,更容易调试。

替代解决方案:

您可能只想为RegisterIfObservableICollection<T>致电IEnumerable<T>,而不仅仅是任何对象。

如果您的方法RegisterIfObservable可以在泛型类中,并且您已经知道元素的类型,那么您可以在没有反射的情况下执行此操作:

public class HelperClass<TU>
{
    public void RegisterIfObservable<T>(T value) where T: ICollection<TU>
    {
        var obs = value as ObservableCollection<T>;
        if (obs!=null)
        {
           ...
        }

    }
}