Próbuję wiedzieć, czy właściwość istnieje w klasie, próbowałem tego:
public static bool HasProperty(this object obj, string propertyName)
{
return obj.GetType().GetProperty(propertyName) != null;
}
Nie rozumiem, dlaczego pierwsza metoda testu nie przechodzi?
[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);
}
c#
.net
reflection
Kris-I
źródło
źródło
MyClass
?Odpowiedzi:
Twoja metoda wygląda następująco:
public static bool HasProperty(this object obj, string propertyName) { return obj.GetType().GetProperty(propertyName) != null; }
To dodaje rozszerzenie do
object
- klasy bazowej wszystkiego . Kiedy dzwonisz na to rozszerzenie, mijasz jeType
:var res = typeof(MyClass).HasProperty("Label");
Twoja metoda oczekuje wystąpienia klasy, a nie
Type
. W przeciwnym razie zasadniczo to robisztypeof(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 słusznie zauważa @PeterRitchie, w tym momencie Twój kod szuka właściwości
Label
naSystem.Type
. Ta nieruchomość nie istnieje.Rozwiązanie jest albo
a) Podaj wystąpienie MyClass do rozszerzenia:
var myInstance = new MyClass() myInstance.HasProperty("Label")
b) Załóż przedłużenie
System.Type
public static bool HasProperty(this Type obj, string propertyName) { return obj.GetProperty(propertyName) != null; }
i
typeof(MyClass).HasProperty("Label");
źródło
, not
.To odpowiada na inne pytanie:
Jeśli próbujesz dowiedzieć się, czy OBIEKT (nie klasa) ma właściwość,
OBJECT.GetType().GetProperty("PROPERTY") != null
zwraca prawdę, jeśli (ale nie tylko jeśli) właściwość istnieje.
W moim przypadku byłem w widoku częściowym ASP.NET MVC i chciałem wyrenderować coś, jeśli właściwość nie istnieje lub właściwość (wartość logiczna) jest prawdziwa.
@if ((Model.GetType().GetProperty("AddTimeoffBlackouts") == null) || Model.AddTimeoffBlackouts)
pomogło mi tutaj.
Edycja: w dzisiejszych czasach prawdopodobnie
nameof
sprytnie jest użyć operatora zamiast nazwy właściwości ze strunami.źródło
nameof
operatora, czy zadziała (nie zgłosi wyjątek), aby uzyskać nazwę właściwości, która może nie istnieć? Skoro przesłanką pierwotnego pytania było to, że nie wiemy, czy ta nieruchomość istnieje?Istnieją 2 możliwości.
Naprawdę nie masz
Label
własności.Musisz wywołać odpowiednie przeciążenie GetProperty i przekazać odpowiednie flagi powiązania, np
BindingFlags.Public | BindingFlags.Instance
Jeśli Twoja nieruchomość nie jest publiczna, będziesz musiał użyć
BindingFlags.NonPublic
lub innej kombinacji flag, która pasuje do twojego przypadku użycia. Przeczytaj dokumentację interfejsu API, do którego się odwołujesz, aby znaleźć szczegółowe informacje.EDYTOWAĆ:
Ojej, Właśnie zauważyłem zadzwonić
GetProperty
natypeof(MyClass)
.typeof(MyClass)
JestType
które na pewno nie maLabel
własności.źródło
Instance|Public|Static
powiązań to iirc.Label
jest to własność prywatna.Otrzymałem ten błąd: „Typ nie zawiera definicji dla GetProperty” podczas wiązania zaakceptowanej odpowiedzi.
Oto, co otrzymałem:
using System.Reflection; if (productModel.GetType().GetTypeInfo().GetDeclaredProperty(propertyName) != null) { }
źródło
Jeśli jesteś wiążący tak jak ja:
<%# Container.DataItem.GetType().GetProperty("Property1") != null ? DataBinder.Eval(Container.DataItem, "Property1") : DataBinder.Eval(Container.DataItem, "Property2") %>
źródło
Nie jestem pewien kontekstu, dlaczego było to potrzebne, więc może to nie zwrócić wystarczającej ilości informacji, ale oto, co udało mi się zrobić:
if(typeof(ModelName).GetProperty("Name of Property") != null) { //whatevver you were wanting to do. }
W moim przypadku przeglądam właściwości z przesłania formularza, a także mam wartości domyślne do użycia, jeśli wpis jest pusty - więc musiałem wiedzieć, czy istnieje wartość do użycia - przedrostkiem wszystkie moje wartości domyślne w modelu z Default, więc wszystko, co musiałem zrobić, to sprawdzić, czy istnieje właściwość, która zaczęła się od tego.
źródło