Как проверить, является ли свойство виртуальным с отражением?
Учитывая объект, как определить, имеет ли этот объект виртуальные свойства?
var entity = repository.GetByID(entityId);
Я пробовал смотреть:
PropertyInfo[] properties = entity.GetType().GetProperties();
Но не смог определить, будет ли какое-либо из свойств указывать виртуальное.
Ответы
Ответ 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);