Как проверить, существует ли свойство в динамическом анонимном типе в c #? - PullRequest
102 голосов
/ 31 марта 2012

У меня есть объект анонимного типа, который я получаю как метод от метода Я хотел бы проверить, существует ли свойство для этого объекта.

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

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

Как мне реализовать IsSettingExist?

Ответы [ 8 ]

121 голосов
/ 31 марта 2012
  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"));

Выход:

 True
 False
31 голосов
/ 29 мая 2015
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;
}
12 голосов
/ 31 марта 2012

если вы можете контролировать создание / передачу объекта настроек, я бы рекомендовал вместо этого использовать 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 ....
}
3 голосов
/ 14 августа 2017

Слияние и исправление ответов от Serj-TM и user3359453, чтобы оно работало как с ExpandoObject, так и с DynamicJsonObject.Это работает для меня.

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;
}
3 голосов
/ 30 июня 2015

Это работает для меня -:

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

               return false;
           }

       }
2 голосов
/ 04 апреля 2017

Ни одно из вышеупомянутых решений не работало для dynamic, полученного из Json, однако мне удалось преобразовать его с Try catch (by @ user3359453), изменив выданный тип исключения (KeyNotFoundException вместо RuntimeBinderException) в то, что на самом деле работает ...

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

enter image description here

Надеюсь, это сэкономит вам время.

2 голосов
/ 02 декабря 2016

Используя отражение, я использую эту функцию:

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

затем ..

if (doesPropertyExist(myDynamicObject, "myProperty")){
    // ...
}
1 голос
/ 12 февраля 2018

Это работает для анонимных типов, ExpandoObject, Nancy.DynamicDictionary или чего-либо еще, что может быть приведено к IDictionary<string, object>.

    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;
    }
...