[英]How can I test if a value is an instance of ObservableCollection<T>?
How can I test if a value is an instance of ObservableCollection?如何测试一个值是否是 ObservableCollection 的实例? (and then operate on the collection, without using dynamic)
(然后对集合进行操作,不使用动态)
How can I remove the dynamic casts from this generic, Coming from Java, I would be able to use wildcard or raw generics in order to operate on the collections, without needing to know the types.如何从这个泛型中删除动态转换,来自 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);
}
Where GetDestination returns an Observable Collection that is the same type as copiedValue其中 GetDestination 返回一个与 CopyValue 类型相同的 Observable 集合
Well, you could use method IsGenericType
combined with GetGenericTypeDefinition
:好吧,您可以将方法
IsGenericType
与GetGenericTypeDefinition
结合使用:
var type = copiedValue.GetType();
if(type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ObservableCollection<>))
type.IsGenericType
is used as a guard clause to prevent against exceptions in GetGenericTypeDefinition
being thrown when called on non generic types. type.IsGenericType
用作保护子句,以防止在调用非泛型类型时抛出GetGenericTypeDefinition
中的异常。
This combined with Magnus's suggestion to cast it to IList
should do the trick.这与 Magnus 将其
IList
为IList
的建议相结合应该可以解决问题。
Since ObservableCollection<T>
implements the non generic interface IList
you can just cast to that.由于
ObservableCollection<T>
实现了非通用接口IList
您可以直接转换为该接口。 IList
excepts object
as parameter. IList
object
作为参数除外。 Example:例子:
var copiedValue = new ObservableCollection<int>() {1,2,3};
var list = (IList)copiedValue;
list.Clear();
for (int i = 4; i < 8; i++)
list.Add(i);
Might be somewhat more maintainable as:可能更易于维护,因为:
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);
}
I created an extension method for such checks:我为此类检查创建了一个扩展方法:
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;
}
Usage:用法:
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);
}
Just after you get to know the type cast it as matching type, like this:就在您了解类型后,将其转换为匹配类型,如下所示:
if(copiedValue is ObservableCollection<Guid>)
{
ObservableCollection<Guid> guids = (ObservableCollection<Guid>)copiedValue
//now deal with guids
}
you may create a switch-case.您可以创建一个开关盒。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.