给出一个对象,我如何分辨该对象是否具有虚拟属性?
var entity = repository.GetByID(entityId);
我尝试查看:
PropertyInfo[] properties = entity.GetType().GetProperties();
但是无法确定是否有任何属性表示虚拟。
PropertyInfo[] properties = entity.GetType().GetProperties()
.Where(p => p.GetMethod.IsVirtual).ToArray();
或者,对于.NET 4及以下版本:
PropertyInfo[] properties = entity.GetType().GetProperties()
.Where(p => p.GetGetMethod().IsVirtual).ToArray();
这将获得公共虚拟属性的列表。
不适用于只写属性。如果需要,您可以手动检查CanRead
和CanWrite
,并阅读适当的方法。
例如:
PropertyInfo[] properties = entity.GetType().GetProperties()
.Where(p => (p.CanRead ? p.GetMethod : p.SetMethod).IsVirtual).ToArray();
您也可以抓住第一个访问者:
PropertyInfo[] properties = entity.GetType().GetProperties()
.Where(p => p.GetAccessors()[0].IsVirtual).ToArray();
仅检查属性访问器的IsVirtual
将为您提供在类中未声明为virtual
的接口属性。如果“虚拟属性”是指可以在派生类中覆盖的属性,则还应该检查IsFinal
(密封):
var accessor = typeof(MyType).GetProperty("MyProp").GetAccessors()[0];
var isVirtual = accessor.IsVirtual && ! accessor.IsFinal;
检查此示例应用程序:
using System;
namespace VirtualPropertyReflection
{
interface I
{
int P1 { get; set; }
int P2 { get; set; }
}
class A : I
{
public int P1 { get; set; }
public virtual int P2 { get; set; }
static void Main()
{
var p1accessor = typeof(A).GetProperty("P1").GetAccessors()[0];
Console.WriteLine(p1accessor.IsVirtual); // True
Console.WriteLine(p1accessor.IsFinal); // True
var p2accessor = typeof(A).GetProperty("P2").GetAccessors()[0];
Console.WriteLine(p2accessor.IsVirtual); // True
Console.WriteLine(p2accessor.IsFinal); // False
}
}
}
请参见this answer。
尝试使用
typeof(YourClass).GetProperty("YouProperty").GetGetMethod().IsVirtual;
例如,对第一个属性使用GetAccessors方法:
获取访问者:
properties[0].GetAccessors()[0].IsVirtual
设置访问者:
properties[0].GetAccessors()[1].IsVirtual
这有点棘手,因为属性可以是只读,只写或读/写的。因此,您需要检查两个基本方法是否为虚拟方法,如下所示:
PropertyInfo pi = ...
var isVirtual = (pi.CanRead && pi.GetMethod.IsVirtual)
|| (pi.CanWrite && pi.SetMethod.IsVirtual);
单独使用IsVirtual并不适合我。告诉我,我所有的非虚拟非空属性都是虚拟的。我必须结合使用IsFinal和IsVirtual
我正在过滤掉所有虚拟属性,所以我的代码看起来像这样:
PropertyInfo[] nonVirtualProperties = myType.GetProperties().Where(x => x.GetAccessors()[0].IsFinal || !x.GetAccessors()[0].IsVirtual).ToArray();
因此,为了回答原始问题:
PropertyInfo[] virtualProperties = myType.GetProperties().Where(x => !x.GetAccessors()[0].IsFinal && x.GetAccessors()[0].IsVirtual).ToArray();