Désolé, je recherche le type System.Type
et le type PropertyInfo
dans la documentation, mais je n'arrive pas à trouver la chose dont j'ai besoin.
Comment savoir si une propriété (ou méthode ou tout autre membre) a été déclarée virtual
dans sa classe déclarante?
Par exemple.
class Cat
{
public string Name { get; set; }
public virtual int Age { get; set; }
}
Comment savoir si la propriété Age
a été déclarée virtual
ou non?
Vous pouvez utiliser le IsVirtual property:
var isVirtual = typeof(Cat).GetProperty("Age").GetGetMethod().IsVirtual;
Techniquement, les propriétés ne sont pas virtuelles, mais leurs accesseurs. Essaye ça:
typeof(Cat).GetProperty("Age").GetAccessors()[0].IsVirtual
Si vous le souhaitez, vous pouvez utiliser une méthode d'extension comme celle-ci pour déterminer si une propriété est virtuelle:
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;
}
S'il renvoie null
, la propriété ne comporte aucun accesseur (ce qui ne devrait jamais se produire) ou tous les accesseurs de la propriété n'ont pas le même statut virtuel (au moins un l'est et l'autre n'est pas virtuel).
Si une classe hérite d'une interface, toutes les propriétés de l'interface sont marquées comme virtuelles. Si vous voulez vérifier si une propriété est redéfinissable, vous devez également vérifier que IsFinal est également faux
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();
}