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

时间:2018-10-24 06:44:47

标签: c# generics

如何测试值是否是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返回与被复制的值类型相同的Observable集合

5 个答案:

答案 0 :(得分:2)

好吧,就像其他通用类型一样,您可以像这样检查它:

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

结合Magnus的建议将其转换为IList应该可以解决问题。

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

答案 1 :(得分:2)

由于ObservableCollection<T>实现了非通用接口IList,因此您可以强制转换为非通用接口。 IListobject作为参数外。 示例:

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

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

答案 2 :(得分:1)

在以下方面可能更具可维护性:

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);
}

答案 3 :(得分:1)

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

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);        
}

答案 4 :(得分:0)

仅在您知道类型后,便将其强制转换为匹配类型,如下所示:

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

您可以创建一个开关盒。