2

如何测试一个值是否是 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 Collection

4

5 回答 5

3

好吧,您可以IsGenericType结合使用方法GetGenericTypeDefinition

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

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

这与 Magnus 的建议相结合,IList应该可以做到这一点。

于 2018-10-24T06:48:00.017 回答
2

由于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);
于 2018-10-24T06:57:02.517 回答
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);
}
于 2018-10-24T06:58:32.467 回答
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);        
}
于 2018-10-24T07:03:33.607 回答
0

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

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

您可以创建一个开关盒。

于 2018-10-24T06:48:16.307 回答