我正在循环给定Type
上的字段和属性,我想测试字段类型或属性类型是否实现INotifyPropertyChanged
。
也许这听起来很奇怪,但我会解析字段/属性,如字符串,整数和其他类型,但我也有一些ObservableCollection
,例如和一些自定义类型,我定义从INotifyPropertyChanged
继承。
所以在我的代码中,我想根据字段或属性是否实现INotifyPropertyChanged
这一事实做一些测试。
您可以使用GetInterface
或GetInterfaces
:
static bool SupportsINotifyPropertyChanged(this Type type)
{
return null != type.GetInterface(typeof(INotifyPropertyChanged).FullName);
// or
// return type.GetInterfaces().Any(x => x == typeof(INotifyPropertyChanged));
}
或者更通用的方法:
static bool SupportsInterface<T>(this Type type)
{
if (!typeof(T).IsInterface) throw new InvalidOperationException();
return type != null && type.GetInterfaces().Any(x => x == typeof(T));
}
假设当你说迭代一个类的字段和属性时,你指的是标准反射,即你有PropertyInfo
和FieldInfo
类型的对象。
对于PropertyInfo
,您可以执行以下操作:
var pi = typeof(DateTime).GetProperty("Now");
var result = pi.PropertyType.GetInterface("INotifiyPropertyChanged");
Console.WriteLine(result != null);
对于FieldInfo
是非常相似的,你只需要使用fi.FieldType.GetInterface("INotifiyPropertyChanged")
。
Update:如果你已经有一个System.Type
的对象,那么你可以直接在该对象上调用GetInterface
方法来检查该给定类型的实例是否实现了特定的接口
建议使用以下模式:
var anyObject = FromTheVoid();
var objAsINotifyPropertyChanged = anyObject as INotifyPropertyChanged;
if(objAsINotifyPropertyChanged != null)
{
objAsINotifyPropertyChanged.PropertyChanged += myHandled;
}
事实上,这取决于你的需要(你是否愿意反映,如果可用的话调用子类方法,等等)。
[Edit] "FxCop: Do not cast不必要地转换"博客文章也解释了为什么使用这种模式更好。
标记为正确的答案并不是确定这一点的最佳方法,如果您有一个系统。键入你只需要这样做:
bool isNotifyPropertyChanged = typeof(INotifyPropertyChanged).IsAssignableFrom(mytype);
我认为你可以这样做。
if (property.Type is INotifyPropertyChanged)
{
//Do something
}
注意,我假设您正在使用反射循环遍历属性,并且该属性的类型为PropertyInfo