C# 如何使用反射检查属性是否是虚拟的?

C# 如何使用反射检查属性是否是虚拟的?,c#,reflection,virtual,C#,Reflection,Virtual,给定一个对象,如何判断该对象是否具有虚拟属性 var entity = repository.GetByID(entityId); 我试着往里面看: PropertyInfo[] properties = entity.GetType().GetProperties(); 但无法辨别是否有任何属性指示虚拟。请尝试使用 typeof(YourClass).GetProperty("YouProperty").GetGetMethod().IsVirtual; 这有点棘手,因为属性可以是只读、

给定一个对象,如何判断该对象是否具有虚拟属性

var entity = repository.GetByID(entityId);
我试着往里面看:

PropertyInfo[] properties = entity.GetType().GetProperties();
但无法辨别是否有任何属性指示虚拟。

请尝试使用

typeof(YourClass).GetProperty("YouProperty").GetGetMethod().IsVirtual;

这有点棘手,因为属性可以是只读、只读或读/写。因此,您需要检查两个底层方法是否都是虚拟的,如下所示:

PropertyInfo pi = ...
var isVirtual = (pi.CanRead && pi.GetMethod.IsVirtual)
             || (pi.CanWrite && pi.SetMethod.IsVirtual);
或者,对于.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();
properties[0].GetAccessors()[0].IsVirtual
properties[0].GetAccessors()[1].IsVirtual

使用GetAccessors方法,例如第一个属性:

获取访问器:

PropertyInfo[] properties = entity.GetType().GetProperties()
    .Where(p => p.GetAccessors()[0].IsVirtual).ToArray();
properties[0].GetAccessors()[0].IsVirtual
properties[0].GetAccessors()[1].IsVirtual
设置访问器:

PropertyInfo[] properties = entity.GetType().GetProperties()
    .Where(p => p.GetAccessors()[0].IsVirtual).ToArray();
properties[0].GetAccessors()[0].IsVirtual
properties[0].GetAccessors()[1].IsVirtual

仅检查属性的访问器的
IsVirtual
,也将为您提供类中未声明的
virtual
接口属性。如果“虚拟属性”是指可以在派生类中重写的属性,则还应选中
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
        }
    }
}

请看。

单独使用虚拟机对我不起作用。它告诉我,我所有的非虚拟不可为空的属性都是虚拟的。我不得不同时使用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();

要安全地处理私有属性,您可以执行以下操作:
(p.CanRead?p.getmethod(true):p.GetSetMethod(true)).IsVirtual谢谢你的回答,很多其他的答案都提到了
isVirtual
,但是组合的
isFinal
检查帮了我。