繁体   English   中英

如何测试值是否是 ObservableCollection 的实例<T> ?

[英]How can I test if a value is an instance of ObservableCollection<T>?

如何测试一个值是否是 ObservableCollection 的实例? (然后对集合进行操作,不使用动态)

如何从这个泛型中删除动态转换,来自 Java,我将能够使用通配符或原始泛型来对集合进行操作,而无需知道类型。

 object copiedValue = FetchCopyValue();
 if( copiedValue is ObservableCollection<Guid> 
  || copiedValue is ObservableCollection<AViewModel>
  || copiedValue is ObservableCollection<BViewModel>
  || copiedValue is ObservableCollection<CViewModel>
  || copiedValue is ObservableCollection<DViewModel>
 )
 {
     var sourceCollection = (dynamic) copiedValue;
     var destinationCollection = (dynamic) GetDestination(copiedValue);
     destinationCollection?.Clear();
     destinationCollection?.AddRange(sourceCollection);
 }

其中 GetDestination 返回一个与 CopyValue 类型相同的 Observable 集合

好吧,您可以将方法IsGenericTypeGetGenericTypeDefinition结合使用:

var type = copiedValue.GetType();
if(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ObservableCollection<>))

type.IsGenericType用作保护子句,以防止在调用非泛型类型时抛出GetGenericTypeDefinition中的异常。

这与 Magnus 将其IListIList的建议相结合应该可以解决问题。

由于ObservableCollection<T>实现了非通用接口IList您可以直接转换为该接口。 IList object作为参数除外。 例子:

var copiedValue = new ObservableCollection<int>() {1,2,3};
var list = (IList)copiedValue;

list.Clear();
for (int i = 4; i < 8; i++)
    list.Add(i);

可能更易于维护,因为:

bool TryAddToDestination<T>(object o)
{
    if (o is ObservableCollection<T> sourceCollection)
    {
       var destinationCollection = GetDestination (sourceCollection);
       destinationCollection?.Clear();
       destinationCollection?.AddRange(sourceCollection);
       return true;
    }
    return false;   
}

void YourFunction()
{
    TryAddToDestination<Guid> || TryAddToDestination<AViewModel> || TryAddToDestination<BViewModel> || TryAddToDestination<CViewModel);
}

我为此类检查创建了一个扩展方法:

public static bool IsGenericTypeOf(this Type type, Type genericTypeDefinition)
{
    if (type == null)
        throw new ArgumentNullException(nameof(type));
    if (genericTypeDefinition == null)
        throw new ArgumentNullException(nameof(genericTypeDefinition));
    return type.IsGenericType && type.GetGenericTypeDefinition() == genericTypeDefinition;
}

用法:

if (copiedValue.IsGenericTypeOf(typeof(ObservableCollection<>)))
{
     // as the element type can be anything you cannot treat copiedValue as ObservableCollection here
     // But considering it implements nongeneric interfaces you can cast it to IList:
     IList sourceCollection = (IList)copiedValue;
     IList destinationCollection = GetDestination(copiedValue);
     destinationCollection.Clear();
     foreach (var item in sourceCollection)
         destinationCollection.Add(item);        
}

就在您了解类型后,将其转换为匹配类型,如下所示:

if(copiedValue is ObservableCollection<Guid>)
{
     ObservableCollection<Guid> guids = (ObservableCollection<Guid>)copiedValue
     //now deal with guids
}

您可以创建一个开关盒。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM