25

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

var entity = repository.GetByID(entityId);

我试着看:

PropertyInfo[] properties = entity.GetType().GetProperties();

但无法辨别是否有任何属性表示虚拟。

4

6 回答 6

41
PropertyInfo[] properties = entity.GetType().GetProperties()
    .Where(p => p.GetMethod.IsVirtual).ToArray();

或者,对于 .NET 4 及以下版本:

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

这将获得一个公共虚拟属性列表。

它不适用于只写属性。如果需要,您可以手动检查CanReadCanWrite阅读相应的方法。

例如:

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();
于 2012-09-06T18:17:21.657 回答
18

仅检查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
        }
    }
}

看到这个答案

于 2013-06-25T13:06:35.080 回答
8

尝试

typeof(YourClass).GetProperty("YouProperty").GetGetMethod().IsVirtual;
于 2012-09-06T18:11:37.010 回答
5

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

获取访问器:

properties[0].GetAccessors()[0].IsVirtual

设置访问器:

properties[0].GetAccessors()[1].IsVirtual
于 2012-09-06T18:18:05.557 回答
3

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

PropertyInfo pi = ...
var isVirtual = (pi.CanRead && pi.GetMethod.IsVirtual)
             || (pi.CanWrite && pi.SetMethod.IsVirtual);
于 2012-09-06T18:12:41.723 回答
0

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();
于 2019-10-31T11:12:02.403 回答