web-dev-qa-db-fra.com

Vérifier si une propriété existe dans une classe

J'essaie de savoir si une propriété existe dans une classe, j'ai essayé ceci:

public static bool HasProperty(this object obj, string propertyName)
{
    return obj.GetType().GetProperty(propertyName) != null;
}

Je ne comprends pas pourquoi la première méthode de test ne passe pas?

[TestMethod]
public void Test_HasProperty_True()
{
    var res = typeof(MyClass).HasProperty("Label");
    Assert.IsTrue(res);
}

[TestMethod]
public void Test_HasProperty_False()
{
    var res = typeof(MyClass).HasProperty("Lab");
    Assert.IsFalse(res);
}
62
Kris-I

Votre méthode ressemble à ceci:

public static bool HasProperty(this object obj, string propertyName)
{
    return obj.GetType().GetProperty(propertyName) != null;
}

Cela ajoute une extension à object - la classe de base de tout . Lorsque vous appelez cette extension, vous lui transmettez une Type:

var res = typeof(MyClass).HasProperty("Label");

Votre méthode attend une instance d'une classe, pas une Type. Sinon, vous faites essentiellement

typeof(MyClass) - this gives an instanceof `System.Type`. 

Ensuite

type.GetType() - this gives `System.Type`
Getproperty('xxx') - whatever you provide as xxx is unlikely to be on `System.Type`

Comme @PeterRitchie le souligne correctement, votre code recherche à ce stade la propriété Label sur System.Type. Cette propriété n'existe pas.

La solution est soit

a) Fournissez une instance de MyClass à l'extension:

var myInstance = new MyClass()
myInstance.HasProperty("Label")

b) Mettez l'extension sur System.Type

public static bool HasProperty(this Type obj, string propertyName)
{
    return obj.GetProperty(propertyName) != null;
}

et

typeof(MyClass).HasProperty("Label");
88
Jamiec

Cela répond à une question différente:

Si vous essayez de savoir si un OBJECT (pas une classe) a une propriété, 

OBJECT.GetType().GetProperty("PROPERTY") != null

renvoie true si (mais pas seulement si) la propriété existe.

Dans mon cas, j'étais dans une vue partielle ASP.NET MVC et je voulais rendre quelque chose si la propriété n'existait pas ou si la propriété (booléen) était vraie.

@if ((Model.GetType().GetProperty("AddTimeoffBlackouts") == null) ||
        Model.AddTimeoffBlackouts)

m'a aidé ici.

Edit: De nos jours, il est probablement intelligent d’utiliser l’opérateur nameof au lieu du nom de la propriété stringified.

16
Stachu

Il y a 2 possibilités.

Vous n'avez vraiment pas la propriété Label.

Vous devez appeler la surcharge appropriée GetProperty et transmettre les indicateurs de liaison appropriés, par exemple. BindingFlags.Public | BindingFlags.Instance

Si votre propriété n'est pas publique, vous devrez utiliser BindingFlags.NonPublic ou une autre combinaison d'indicateurs adaptée à votre cas d'utilisation. Lisez les documents de l'API référencés pour trouver les détails.

MODIFIER:

ooops, je viens de remarquer que vous appelez GetProperty à typeof(MyClass). typeof(MyClass) est Type qui, à coup sûr, n'a pas de propriété Label.

2
Zdeslav Vojkovic

J'ai eu cette erreur: "Type ne contient pas de définition pour GetProperty" en liant la réponse acceptée.

C'est ce que j'ai fini avec:

using System.Reflection;

if (productModel.GetType().GetTypeInfo().GetDeclaredProperty(propertyName) != null)
{

}
1
JedatKinports

Je ne suis pas sûr du contexte sur la raison pour laquelle cela était nécessaire, donc cela ne vous retournera peut-être pas assez d'informations mais voici ce que j'ai pu faire:

if(typeof(ModelName).GetProperty("Name of Property") != null)
{
//whatevver you were wanting to do.
}

Dans mon cas, je suis en train de parcourir les propriétés d'une soumission de formulaire et j'ai aussi des valeurs par défaut à utiliser si l'entrée est laissée en blanc - j'ai donc besoin de savoir s'il y avait une valeur à utiliser - j'ai préfixé toutes mes valeurs par défaut dans le modèle avec Par défaut tout ce que j'avais à faire est de vérifier s'il y avait une propriété qui a commencé avec cela.

0
C Gil

Si vous vous engagez comme je l'étais:

<%# Container.DataItem.GetType().GetProperty("Property1") != null ? DataBinder.Eval(Container.DataItem, "Property1") : DataBinder.Eval(Container.DataItem, "Property2")  %>
0
Ben