如何通过反射检查属性是否为虚拟?

Tra*_*s J 21 c# reflection virtual

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

var entity = repository.GetByID(entityId);
Run Code Online (Sandbox Code Playgroud)

我试过看:

PropertyInfo[] properties = entity.GetType().GetProperties();
Run Code Online (Sandbox Code Playgroud)

但无法辨别出任何属性是否表示虚拟.

Ken*_*rey 36

PropertyInfo[] properties = entity.GetType().GetProperties()
    .Where(p => p.GetMethod.IsVirtual).ToArray();
Run Code Online (Sandbox Code Playgroud)

或者,对于.NET 4及更低版本:

PropertyInfo[] properties = entity.GetType().GetProperties()
    .Where(p => p.GetGetMethod().IsVirtual).ToArray();
Run Code Online (Sandbox Code Playgroud)

这将获得公共虚拟属性的列表.

它不适用于只写属性.如果需要,你可以检查CanReadCanWrite手工,阅读和适当的方法.

例如:

PropertyInfo[] properties = entity.GetType().GetProperties()
    .Where(p => (p.CanRead ? p.GetMethod : p.SetMethod).IsVirtual).ToArray();
Run Code Online (Sandbox Code Playgroud)

你也可以抓住第一个访问者:

PropertyInfo[] properties = entity.GetType().GetProperties()
    .Where(p => p.GetAccessors()[0].IsVirtual).ToArray();
Run Code Online (Sandbox Code Playgroud)


fok*_*oka 15

仅检查IsVirtual属性的访问者将为您提供未virtual在类中声明的界面属性.如果"虚拟属性"是指您可以在派生类中覆盖的属性,则还应检查IsFinal(密封):

var accessor = typeof(MyType).GetProperty("MyProp").GetAccessors()[0];
var isVirtual = accessor.IsVirtual && ! accessor.IsFinal;
Run Code Online (Sandbox Code Playgroud)

检查此示例应用:

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

看到这个答案.

  • 感谢这一点,许多其他答案都谈到了“isVirtual”,但组合的“isFinal”检查为我做到了。 (3认同)

Agh*_*oub 8

尝试

typeof(YourClass).GetProperty("YouProperty").GetGetMethod().IsVirtual;
Run Code Online (Sandbox Code Playgroud)


Erw*_*win 5

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

获取访问者:

properties[0].GetAccessors()[0].IsVirtual
Run Code Online (Sandbox Code Playgroud)

设置访问者:

properties[0].GetAccessors()[1].IsVirtual
Run Code Online (Sandbox Code Playgroud)