2012-03-31 13 views
65

Ich habe ein anonymen Typ Objekt, das ich als eine dynamische erhalten von einer Methode Ich möchte eine Eigenschaft für dieses Objekt einchecken.Wie überprüfe ich, ob eine Eigenschaft für einen dynamischen anonymen Typ in C# existiert?

.... 
var settings = new { 
        Filename="temp.txt", 
        Size=10 
} 
... 

function void Settings(dynamic settings) { 
var exists = IsSettingExist(settings,"Filename") 
} 

Wie würde ich IsSettingExist implementieren?

+2

Mögliches Duplikat von [Wie erkennen, ob eine Eigenschaft auf einem ExpandoObject existiert?] (Http://stackoverflow.com/questions/2839598/how-to-detect-if-a-property-exists-on -an-expandoobject) – Sebastian

Antwort

92
public static bool IsPropertyExist(dynamic settings, string name) 
    { 
    if (settings is ExpandoObject) 
     return ((IDictionary<string, object>)settings).ContainsKey(name); 

    return settings.GetType().GetProperty(name) != null; 
    } 

    var settings = new {Filename = @"c:\temp\q.txt"}; 
    Console.WriteLine(IsPropertyExist(settings, "Filename")); 
    Console.WriteLine(IsPropertyExist(settings, "Size")); 

Ausgang:

True 
False 
+11

Dies funktioniert nicht in allen Fällen: http://stackoverflow.com/a/11540889/238419 –

+1

Dies funktioniert nicht bei dynamischen Objekten. Es gibt immer null zurück. – evilom

+0

Das funktioniert nicht. –

11

Wenn Sie das Erstellen/Übergeben des Einstellungsobjekts steuern können, empfehle ich stattdessen die Verwendung eines ExpandoObject.

dynamic settings = new ExpandoObject(); 
settings.Filename = "asdf.txt"; 
settings.Size = 10; 
... 

function void Settings(dynamic settings) 
{ 
    if (((IDictionary<string, object>)settings).ContainsKey("Filename")) 
     .... do something .... 
} 
+0

Ich kann es nicht ändern, kann ich nach ExpendoObject umwandeln? –

25
public static bool HasProperty(dynamic obj, string name) 
{ 
    Type objType = obj.GetType(); 

    if (objType == typeof(ExpandoObject)) 
    { 
     return ((IDictionary<string, object>)obj).ContainsKey(name); 
    } 

    return objType.GetProperty(name) != null; 
} 
+0

'objType.GetProperty (name)! = Null;' gibt null für Eigenschaften zurück, die existieren –

+1

'objType.GetProperty (name)! = Null 'wird gebe immer einen 'bool' zurück, der (definitionsgemäß) niemals' null' sein kann. –

+0

@AlexMcMillan Nicht sicher, in welcher Dimension Sie leben, wobei 'Type.GetProperty (String)' für eine nicht vorhandene Eigenschaft einen anderen Wert als null zurückgibt. –

3

Dies ist für me- Arbeits:

public static bool IsPropertyExist(dynamic dynamicObj, string property) 
     { 
      try 
      { 
       var value=dynamicObj[property].Value; 
       return true; 
      } 
      catch (RuntimeBinderException) 
      { 

       return false; 
      } 

     } 
+10

Es ist keine bevorzugte Lösung, Ausnahmen zuzulassen und dann abzufangen, da mit Werfen und Fangen viel Aufwand verbunden ist. Es ist nur ein letzter Ausweg. Ausnahmen sind für Situationen gedacht, in denen * es * im Verlauf der Ausführung nicht passieren sollte, dass ein Netzwerk nicht verfügbar ist. Hier gibt es viel bessere Lösungen. –

+0

Fehler bei 'RuntimeBinderException' und' dynamicObj [property] .Value', wenn der Wert tatsächlich da ist ... 'var value = dynamicObj [property]' ist genug ... und wenn es '' '' '' '' '' nicht existiert wird geworfen ... siehe unten ... –

0

Reflexion verwenden, ist dies die Funktion i verwenden:

public static bool doesPropertyExist(dynamic obj, string property) 
{ 
    return ((Type)obj.GetType()).GetProperties().Where(p => p.Name.Equals(property)).Any(); 
} 

dann ..

if (doesPropertyExist(myDynamicObject, "myProperty")){ 
    // ... 
} 
1

Keine der oben genannten Lösungen für dynamic gearbeitet, die von Json kommt, ich schaffte es jedoch eine mit Try catch zu transformieren (von @ user3359453) durch Ausnahmetyp zu ändern geworfen (KeyNotFoundException statt RuntimeBinderException) in etwas, das tatsächlich funktioniert ...

public static bool HasProperty(dynamic obj, string name) 
    { 
     try 
     { 
      var value = obj[name]; 
      return true; 
     } 
     catch (KeyNotFoundException) 
     { 
      return false; 
     } 
    } 

enter image description here

Hoffe das spart Ihnen etwas Zeit.

+1

dieser arbeitete für mich. Vielen Dank! – Carlos

1

Zusammenführen und Reparieren der Antworten von Serj-TM und user3359453, sodass es sowohl mit ExpandoObject als auch mit DynamicJsonObject funktioniert. Das funktioniert für mich.

public static bool HasPropertyExist(dynamic settings, string name) 
{ 
    if (settings is System.Dynamic.ExpandoObject) 
     return ((IDictionary<string, object>)settings).ContainsKey(name); 

    if (settings is System.Web.Helpers.DynamicJsonObject) 
    try 
    { 
     return settings[name] != null; 
    } 
    catch (KeyNotFoundException) 
    { 
     return false; 
    } 


    return settings.GetType().GetProperty(name) != null; 
} 
0

Dies funktioniert für anonyme Typen, ExpandoObject, Nancy.DynamicDictionary oder irgendetwas anderes, das zu IDictionary<string, object> gegossen werden kann.

public static bool PropertyExists(dynamic obj, string name) { 
     if (obj == null) return false; 
     if (obj is IDictionary<string, object> dict) { 
      return dict.ContainsKey(name); 
     } 
     return obj.GetType().GetProperty(name) != null; 
    } 
Verwandte Themen