W javascript możesz wykryć, czy właściwość jest zdefiniowana za pomocą niezdefiniowanego słowa kluczowego:
if( typeof data.myProperty == "undefined" ) ...
Jak zrobiłbyś to w C # używając dynamicznego słowa kluczowego ExpandoObject
zi bez zgłaszania wyjątku?
c#
dynamic
expandoobject
Softlion
źródło
źródło
data.myProperty
; sprawdza, cotypeof data.myProperty
zwraca. To prawda, żedata.myProperty
może istnieć i być ustawioneundefined
, ale w takim przypadkutypeof
zwróci coś innego niż"undefined"
. Więc ten kod działa.Odpowiedzi:
Według MSDN deklaracja pokazuje, że implementuje IDictionary:
Możesz użyć tego, aby sprawdzić, czy członek jest zdefiniowany:
źródło
Należy tu dokonać istotnego rozróżnienia.
Większość odpowiedzi tutaj jest specyficznych dla ExpandoObject, który jest wymieniony w pytaniu. Ale powszechnym zastosowaniem (i powodem, dla którego warto znaleźć to pytanie podczas wyszukiwania) jest użycie ASP.Net MVC ViewBag. Jest to niestandardowa implementacja / podklasa DynamicObject, która nie zgłosi wyjątku, gdy sprawdzisz dowolną nazwę właściwości pod kątem wartości null. Załóżmy, że możesz zadeklarować właściwość taką jak:
Załóżmy, że chcesz sprawdzić jego wartość i czy w ogóle jest ustawiona - czy istnieje. Poniższe informacje są prawidłowe, będą się kompilować, nie będą zgłaszać żadnych wyjątków i dadzą właściwą odpowiedź:
Teraz pozbądź się deklaracji EnableThinger. Ten sam kod kompiluje się i działa poprawnie. Nie ma potrzeby refleksji.
W przeciwieństwie do ViewBag, ExpandoObject wyrzuci, jeśli zaznaczysz null dla właściwości, która nie istnieje. Aby uzyskać delikatniejszą funkcjonalność MVC ViewBag z twoich
dynamic
obiektów, musisz użyć implementacji dynamiki, która nie rzuca.Możesz po prostu użyć dokładnej implementacji w MVC ViewBag:
https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/DynamicViewDataDictionary.cs
Możesz zobaczyć, że jest on powiązany z widokami MVC tutaj, w MVC ViewPage:
http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/ViewPage.cs
Kluczem do wdzięcznego zachowania DynamicViewDataDictionary jest implementacja Dictionary na ViewDataDictionary, tutaj:
https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/ViewDataDictionary.cs
Innymi słowy, zawsze zwraca wartość dla wszystkich kluczy, niezależnie od tego, co jest w środku - po prostu zwraca wartość null, gdy nic tam nie ma. Ale ViewDataDictionary ma ciężar związany z modelem MVC, więc lepiej jest usunąć tylko pełne wdzięku części słownika do użycia poza widokami MVC.
Naprawdę za długo, żeby opublikować tutaj wszystkie wnętrzności - większość z nich to tylko implementacja IDictionary - ale tutaj jest dynamiczny obiekt (klasa
DDict
), który nie wyrzuca zerowych kontroli właściwości, które nie zostały zadeklarowane, na Github:https://github.com/b9chris/GracefulDynamicDictionary
Jeśli chcesz tylko dodać go do swojego projektu za pomocą NuGet, jego nazwa to GracefulDynamicDictionary .
źródło
Odpowiedziałem ostatnio na bardzo podobne pytanie: jak mogę zastanowić się nad elementami dynamicznego obiektu?
Krótko mówiąc, ExpandoObject nie jest jedynym dynamicznym obiektem, który możesz uzyskać. Odbicie działałoby dla typów statycznych (typy, które nie implementują IDynamicMetaObjectProvider). W przypadku typów, które implementują ten interfejs, odbicie jest w zasadzie bezużyteczne. W przypadku ExpandoObject możesz po prostu sprawdzić, czy właściwość jest zdefiniowana jako klucz w podstawowym słowniku. W przypadku innych implementacji może to być trudne, a czasem jedynym sposobem jest praca z wyjątkami. Aby uzyskać szczegółowe informacje, kliknij powyższy link.
źródło
ZAKTUALIZOWANO: Możesz użyć delegatów i spróbować uzyskać wartość z właściwości obiektu dynamicznego, jeśli istnieje. Jeśli nie ma właściwości, po prostu złap wyjątek i zwróć false.
Spójrz, działa dla mnie dobrze:
Kod wyjściowy jest następujący:
źródło
IsPropertyExist
. W tym przykładzie wiesz, że można rzucićInvalidOperationException
. W praktyce nie masz pojęcia, jaki wyjątek może zostać zgłoszony. +1, aby przeciwdziałać kultowi ładunku.Chciałem stworzyć metodę rozszerzenia, aby móc zrobić coś takiego:
... ale nie możesz tworzyć rozszerzeń
ExpandoObject
zgodnie z dokumentacją w C # 5 (więcej informacji tutaj ).Więc ostatecznie stworzyłem pomocnika klasy:
Aby go użyć:
źródło
Dlaczego nie chcesz używać Reflection, aby uzyskać zestaw propery typu? Lubię to
źródło
Ta metoda rozszerzenia sprawdza istnienie właściwości, a następnie zwraca wartość lub wartość null. Jest to przydatne, jeśli nie chcesz, aby aplikacje zgłaszały niepotrzebne wyjątki, przynajmniej takie, w których możesz pomóc.
Jeśli może być używany jako taki:
lub jeśli twoja zmienna lokalna jest „dynamiczna”, musisz najpierw rzucić ją na ExpandoObject.
źródło
W zależności od przypadku użycia, jeśli wartość null może być uznana za taką samą jak niezdefiniowana, możesz zmienić ExpandoObject w DynamicJsonObject.
Wynik:
źródło
źródło
Hej, przestańcie używać Reflection do wszystkiego, co kosztuje dużo cykli procesora.
Oto rozwiązanie:
źródło
Spróbuj tego
źródło
dynamic
obiektami (zawsze zwracanull
).