Подтвердить что ты не робот

Как проверить, является ли свойство виртуальным с отражением?

Учитывая объект, как определить, имеет ли этот объект виртуальные свойства?

var entity = repository.GetByID(entityId);

Я пробовал смотреть:

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

Но не смог определить, будет ли какое-либо из свойств указывать виртуальное.

4b9b3361

Ответ 1

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();

Ответ 2

Проверка только IsVirtual свойства accessor даст вам также свойства интерфейса, которые не объявлены 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
        }
    }
}

См. этот ответ.

Ответ 3

попробуйте

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

Ответ 4

Используйте метод GetAccessors, например, для первого свойства:

Получить accessor:

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

Установить accessor:

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

Ответ 5

Это немного сложно, потому что свойство может быть только для чтения, только для записи или чтения/записи. Поэтому вам нужно проверить оба базовых метода для того, чтобы быть виртуальными, например:

PropertyInfo pi = ...
var isVirtual = (pi.CanRead && pi.GetMethod.IsVirtual)
             || (pi.CanWrite && pi.SetMethod.IsVirtual);