2013-03-11 17 views
40

staram się dowiedzieć, czy właściwość istnieje w klasie, to próbowałem:Sprawdź, czy właściwość istnieje w klasie

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

Nie rozumiem, dlaczego pierwsza metoda testu nie przejdzie?

[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); 
} 
+2

Mógłbyś opublikowania odpowiedni kod z 'MyClass'? – nattyddubbs

Odpowiedz

62

Twoja metoda wygląda następująco:

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

Dodaje rozszerzenie na object - klasę bazową wszystko. Podczas rozmowy telefonicznej to rozszerzenie jesteś przechodzącą mu Type:

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

Twoja metoda oczekuje instancji z klasą, a nie Type. W przeciwnym razie jesteś w zasadzie robi

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

Następnie

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

Jak @PeterRitchie słusznie zauważa, w tym momencie Twój kod poszukuje nieruchomości Label na System.Type. Ta właściwość nie istnieje.

Roztwór albo

a) przedstawią wystąpienie z MojaKlasa do rozszerzenia:

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

b) wprowadzenia rozszerzenie na System.Type

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

i

typeof(MyClass).HasProperty("Label"); 
+2

tzn. Twój kod szuka "Type.Label', a nie' MyClass.Label'. –

+0

W jaki sposób można umieścić to na rozszerzeniu System.Type gdzie by to znaleźć /. Gdzie to jest w kodzie do wykonania? – Demodave

+1

@Demodave - metody rozszerzenia są tylko w publicznej klasie statycznej. Zobacz tutaj, aby uzyskać więcej informacji: https://msdn.microsoft.com/en-GB/library/bb383977.aspx – Jamiec

2

Dostępne są 2 możliwości.

Naprawdę nie masz własności Label.

Musisz wywołać odpowiedni numer GetProperty overload i podać poprawne flagi powiązania, np. BindingFlags.Public | BindingFlags.Instance

Jeśli Twoja nieruchomość nie jest publiczna, musisz użyć BindingFlags.NonPublic lub innej kombinacji flag, która pasuje do Twojego przypadku użycia. Przeczytaj przywoływane dokumenty API, aby znaleźć szczegółowe informacje.

EDIT:

Ojej, właśnie zauważyłem zadzwonić GetProperty na typeof(MyClass). typeof(MyClass) to Type, która na pewno nie ma właściwości Label.

+0

Domyślne używane flagi oprawy to 'Instance | Public | Static', iirc. – LukeH

+0

@LukeH, nie byłem pewien, więc napisałem "poprawny" i dodano "np" :) może "Label" jest własnością prywatną. –

10

To odpowiada na inne pytanie, ale mam nadzieję, że może to być pomocne dla kogoś czytającego to.Szukałem nieco inny problem i to było moje rozwiązanie:

Jeśli próbuje dowiedzieć się, czy dany przedmiot (nie klasa) ma właściwość,

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

Zwraca true jeśli (ale nie tylko wtedy) właściwość istnieje.

W moim przypadku byłem w częściowym widoku ASP.NET MVC i chciałem renderować coś, jeśli właściwość nie istnieje lub właściwość (boolean) była prawdziwa.

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

pomógł mi tutaj.

+0

Dokładnie to, czego potrzebowałem, dzięki za umieszczenie tego! – Rob

0

Jeśli są wiążące jakbym był:

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

mam ten błąd: „Type nie zawierają definicji dla GetProperty” podczas wiązania zaakceptowane odpowiedź.

To, co skończyło się z:

using System.Reflection; 

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

} 
Powiązane problemy