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

Узнайте, объявлено ли свойство виртуальным

Извините, я ищу тип System.Type и тип PropertyInfo в документации, но я не могу найти нужную вещь.

Как узнать, объявлено ли свойство (или метод или любой другой член) virtual в классе объявления?

Например,

class Cat
{
    public string Name { get; set; }
    public virtual int Age { get; set; }
}

Как узнать, было ли объявлено свойство Age virtual или нет?

4b9b3361

Ответ 1

Вы можете использовать свойство IsVirtual:

var isVirtual = typeof(Cat).GetProperty("Age").GetGetMethod().IsVirtual;

Ответ 2

Технически свойства не являются виртуальными - их аксессоры являются. Попробуйте следующее:

typeof(Cat).GetProperty("Age").GetAccessors()[0].IsVirtual

Если вы хотите, вы можете использовать метод расширения, подобный приведенному ниже, чтобы определить, является ли свойство виртуальным:

public static bool? IsVirtual(this PropertyInfo self)
{
    if (self == null)
        throw new ArgumentNullException("self");

    bool? found = null;

    foreach (MethodInfo method in self.GetAccessors()) {
        if (found.HasValue) {
            if (found.Value != method.IsVirtual)
                return null;
        } else {
            found = method.IsVirtual;
        }
    }

    return found;
}

Если он возвращает null, либо свойство не имеет доступа (которое никогда не должно произойти), либо все аксессоры свойств не имеют того же виртуального статуса - по крайней мере один из них и один не является виртуальным.

Ответ 3

Если класс наследует от интерфейса, все свойства интерфейса помечаются как виртуальные. Если вы хотите проверить, является ли свойство перезаписываемым, вы должны проверить, что IsFinal также имеет значение false

public static bool IsPropertyOverridable(this PropertyInfo propertyInfo)
{
    return (propertyInfo.IsGetPropertyVirtual() || propertyInfo.IsSetPropertyOverridable());
}

public static bool IsGetPropertyVirtual(this PropertyInfo propertyInfo)
{
    if (false == propertyInfo.CanRead)
    {
        return false;
    }
    return propertyInfo.GetGetMethod(nonPublic: true).IsOverridable();
}

public static bool IsSetPropertyOverridable(this PropertyInfo propertyInfo)
{
    if (false == propertyInfo.CanWrite)
    {
        return false;
    }
    return propertyInfo.GetSetMethod(nonPublic: true).IsOverridable();
}