In Javascript können Sie mithilfe des undefinierten Schlüsselworts feststellen, ob eine Eigenschaft definiert ist:
if( typeof data.myProperty == "undefined" ) ...
Wie würden Sie dies in C # tun, indem Sie das dynamische Schlüsselwort mit ExpandoObject
und ohne Ausnahmebedingung verwenden?
c#
dynamic
expandoobject
Softlion
quelle
quelle
data.myProperty
. es prüft, wastypeof data.myProperty
zurückkommt. Es ist richtig, dass esdata.myProperty
möglicherweise existiert und auf gesetzt istundefined
, aber in diesem Falltypeof
wird etwas anderes als zurückgegeben"undefined"
. Dieser Code funktioniert also.Antworten:
Laut MSDN zeigt die Erklärung, dass IDictionary implementiert wird:
Sie können dies verwenden, um festzustellen, ob ein Mitglied definiert ist:
quelle
Hier muss eine wichtige Unterscheidung getroffen werden.
Die meisten Antworten hier beziehen sich speziell auf das ExpandoObject, das in der Frage erwähnt wird. Eine häufige Verwendung (und ein Grund, bei der Suche auf diese Frage zu stoßen) ist die Verwendung des ASP.Net MVC ViewBag. Dies ist eine benutzerdefinierte Implementierung / Unterklasse von DynamicObject, die keine Ausnahme auslöst, wenn Sie einen beliebigen Eigenschaftsnamen auf null prüfen. Angenommen, Sie deklarieren eine Eigenschaft wie:
Angenommen, Sie möchten den Wert überprüfen und prüfen, ob er überhaupt festgelegt ist - ob er vorhanden ist. Folgendes ist gültig, wird kompiliert, wirft keine Ausnahmen und gibt Ihnen die richtige Antwort:
Entfernen Sie jetzt die Deklaration von EnableThinger. Der gleiche Code wird kompiliert und ordnungsgemäß ausgeführt. Keine Notwendigkeit zum Nachdenken.
Im Gegensatz zu ViewBag wird ExpandoObject ausgelöst, wenn Sie eine nicht vorhandene Eigenschaft auf Null prüfen. Um die sanftere Funktionalität von MVC ViewBag aus Ihren
dynamic
Objekten herauszuholen , müssen Sie eine Implementierung von Dynamic verwenden, die nicht funktioniert.Sie können einfach die genaue Implementierung in MVC ViewBag verwenden:
https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/DynamicViewDataDictionary.cs
Sie können sehen, dass es in MVC Views hier in MVC ViewPage eingebunden ist:
http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/ViewPage.cs
Der Schlüssel für das elegante Verhalten von DynamicViewDataDictionary ist die Dictionary-Implementierung in ViewDataDictionary.
https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/ViewDataDictionary.cs
Mit anderen Worten, es gibt immer einen Wert für alle Schlüssel zurück, unabhängig davon, was darin enthalten ist - es gibt einfach null zurück, wenn nichts da ist. ViewDataDictionary muss jedoch an das MVC-Modell gebunden sein. Daher ist es besser, nur die eleganten Wörterbuchteile für die Verwendung außerhalb von MVC Views zu entfernen.
Es ist zu lang, um wirklich alle Eingeweide hier zu veröffentlichen - das meiste davon implementiert nur IDictionary -, aber hier ist ein dynamisches Objekt (Klasse
DDict
), das keine Nullprüfungen für nicht deklarierte Eigenschaften auf Github auslöst:https://github.com/b9chris/GracefulDynamicDictionary
Wenn Sie es nur über NuGet zu Ihrem Projekt hinzufügen möchten, heißt es GracefulDynamicDictionary .
quelle
Ich habe kürzlich eine sehr ähnliche Frage beantwortet: Wie reflektiere ich über die Mitglieder eines dynamischen Objekts?
In Kürze ist ExpandoObject nicht das einzige dynamische Objekt, das Sie erhalten könnten. Die Reflexion würde für statische Typen funktionieren (Typen, die IDynamicMetaObjectProvider nicht implementieren). Für Typen, die diese Schnittstelle implementieren, ist die Reflexion grundsätzlich nutzlos. Bei ExpandoObject können Sie einfach überprüfen, ob die Eigenschaft als Schlüssel im zugrunde liegenden Wörterbuch definiert ist. Bei anderen Implementierungen kann dies eine Herausforderung sein, und manchmal besteht die einzige Möglichkeit darin, mit Ausnahmen zu arbeiten. Für Details folgen Sie dem Link oben.
quelle
AKTUALISIERT: Sie können Delegaten verwenden und versuchen, einen Wert aus der dynamischen Objekteigenschaft abzurufen, falls vorhanden. Wenn keine Eigenschaft vorhanden ist, fangen Sie einfach die Ausnahme ab und geben Sie false zurück.
Schau mal, es funktioniert gut für mich:
Die Ausgabe des Codes ist die folgende:
quelle
IsPropertyExist
. In diesem Beispiel wissen Sie, dass man einen werfen kannInvalidOperationException
. In der Praxis haben Sie keine Ahnung, welche Ausnahme ausgelöst werden kann. +1, um dem Frachtkult entgegenzuwirken.Ich wollte eine Erweiterungsmethode erstellen , damit ich Folgendes tun kann:
... aber Sie können keine Erweiterungen
ExpandoObject
gemäß der C # 5-Dokumentation erstellen (weitere Informationen hier ).Also habe ich einen Klassenhelfer geschaffen:
Um es zu benutzen:
quelle
Warum möchten Sie Reflection nicht verwenden, um eine Reihe von Typ-Eigenschaften zu erhalten? So was
quelle
Diese Erweiterungsmethode prüft, ob eine Eigenschaft vorhanden ist, und gibt dann den Wert oder null zurück. Dies ist nützlich, wenn Sie nicht möchten, dass Ihre Anwendungen unnötige Ausnahmen auslösen, zumindest solche, denen Sie helfen können.
Wenn als solches verwendet werden kann:
oder wenn Ihre lokale Variable 'dynamisch' ist, müssen Sie sie zuerst in ExpandoObject umwandeln.
quelle
Abhängig von Ihrem Anwendungsfall können Sie Ihr ExpandoObject in ein DynamicJsonObject verwandeln, wenn null als mit undefiniert identisch angesehen werden kann.
Ausgabe:
quelle
quelle
Hey Leute, hört auf, Reflection für alles zu verwenden, was viele CPU-Zyklen kostet.
Hier ist die Lösung:
quelle
Probier diese
quelle
dynamic
Objekten (wird immer zurückgegebennull
).