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


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

var entity = repository.GetByID(entityId);

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

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

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


19


источник


Ответы:


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

33



Только проверка 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
        }
    }
}

Видеть этот ответ ,


12



попробуйте

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

8



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

Получить доступ:

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

Установить аксессуар:

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

5



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

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

3