检查对象是否为可观察集合

本文关键字:观察 集合 对象 是否 检查 | 更新日期: 2023-09-27 18:31:41

我想检查一个值是否属于任何类型的 ObservableCollection 类型,或者不是在 C# 中?

例如:我可以检查值是否为字符串类型,如下所示:

string value = "value to Check";
bool b = value.GetType().Equals(typeof(string));  // b =true

但是如果我需要检查一个值是否是可观察集合,无论成分类型如何,我该怎么做?

例如:

ObservableCollection<T> collection = new ObservableCollection<T>();

如果我像这样检查

bool b = collection.GetType().Equals(typeof(ObservableCollection<>)); // b=false

如何检查值是否为集合?

检查对象是否为可观察集合

尝试

bool b = collection.GetType().IsGenericType &&
           collection.GetType().GetGenericTypeDefinition() == typeof(ObservableCollection<>);

你可以这样检查:

public static bool IsObservableCollection(object candidate) {
    if (null == candidate) return false;
    var theType = candidate.GetType();
    bool itIs = theType.IsGenericType() && 
        !theType.IsGenericTypeDefinition()) &&
        (theType.GetGenericTypeDefinition() == typeof(ObservableCollection<>));
    return itIs;
}

您还可以获取元素类型:

public static Type GetObservableCollectionElement(object candidate) {
    bool isObservableCollection = IsObservableCollection(candidate);
    if (!isObservableCollection) return null;
    var elementType = candidate.GetType().GetGenericArguments()[0];
    return elementType;
}

编辑

实际上,以动态方式使用ObservableCollection有点棘手。如果你看一下ObservableCollection<T>类:

ObservableCollection<T> : Collection<T>, INotifyCollectionChanged, INotifyPropertyChanged

您会注意到它扩展了Collection<T>并实现了 2 个接口。

因此,由于每个Collection<T>也是一个非泛型IEnumerable因此您可以像这样对动态已知的 ObservableCollection 进行推理:

object someObject = ...
bool itsAnObservableCollection = IsObservableCollection(someObject);
if (itsAnObservableCollection) {
    IEnumerable elements = someObject as IEnumerable;
    // and try to reason about the elements in this manner
    foreach (var element in elements) { ... }
    INotifyCollectionChanged asCC = someObject as INotifyCollectionChanged;
    INotifyPropertyChanged asPC = someObject as INotifyPropertyChanged;
    // and try to let yourself receive notifications in this manner
    asCC.CollectionChanged += (sender, e) => {
        var newItems = e.NewItems;
        var oldItems = e.OldItems; 
        ...
    };     
    asPC.PropertyChanged += (sender, e) => {
        var propertyName = e.PropertyName;
        ...
    };   
}

根据您需要它的目的,您还可以检查它是否实现了INotifyCollectionChanged

if (someCollection is INotifyCollectionChanged observable)
    observable.CollectionChanged += CollectionChanged;

集合的类型是泛型的,你想要测试类型的泛型定义:

collection.GetType()
  .GetGenericTypeDefinition()
  .Equals(typeof(ObservableCollection<>))