c# - 如何检查属性是否存在于c#中的动态匿名类型?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9956648/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 11:23:19  来源:igfitidea点击:

How do I check if a property exists on a dynamic anonymous type in c#?

c#c#-4.0dynamicreflection.net-4.0

提问by David MZ

I have an anonymous type object that I receive as a dynamic from a method I would like to check in a property exists on that object.

我有一个匿名类型对象,我从我想检查该对象上存在的属性的方法中作为动态接收。

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

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

How would I implement IsSettingExist ?

我将如何实现 IsSettingExist ?

采纳答案by Serj-Tm

  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"));

Output:

输出:

 True
 False

回答by Mike Corcoran

if you can control creating/passing the settings object, i'd recommend using an ExpandoObject instead.

如果您可以控制创建/传递设置对象,我建议您改用 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 ....
}

回答by Sergey

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

回答by user3359453

This is working for me-:

这对我有用-:

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

               return false;
           }

       }

回答by Chtiwi Malek

Using reflection, this is the function i use :

使用反射,这是我使用的功能:

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

then..

然后..

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

回答by Matas Vaitkevicius

None of the solutions above worked for dynamicthat comes from Json, I however managed to transform one with Try catch(by @user3359453) by changing exception type thrown (KeyNotFoundExceptioninstead of RuntimeBinderException) into something that actually works...

上面的解决方案dynamic都没有来自Json,但是我设法Try catch通过将抛出的异常类型(KeyNotFoundException而不是RuntimeBinderException)更改为实际工作的东西来转换(由@user3359453)...

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

enter image description here

在此处输入图片说明

Hope this saves you some time.

希望这可以为您节省一些时间。

回答by Bruno Marotta

Merging and fixing answers from Serj-TM and user3359453 so that it works with both ExpandoObject and DynamicJsonObject. This works for me.

合并和修复来自 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;
}

回答by Seth Reno

This works for anonymous types, ExpandoObject, Nancy.DynamicDictionaryor anything else that can be cast to IDictionary<string, object>.

这适用于匿名类型ExpandoObjectNancy.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;
    }

回答by Kuroro

In case someone need to handle a dynamic object come from Json, I has modified Seth Reno answer to handle dynamic object deserialized from NewtonSoft.Json.JObjcet.

如果有人需要处理来自 Json 的动态对象,我已修改 Seth Reno 答案以处理从 NewtonSoft.Json.JObjcet 反序列化的动态对象。

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

回答by M?tz

To extend the answer from @Kuroro, if you need to test if the property is empty, below should work.

为了扩展@Kuroro 的答案,如果您需要测试该属性是否为空,下面应该可以工作。

public static bool PropertyExistsAndIsNotNull(dynamic obj, string name)
{
    if (obj == null) return false;
    if (obj is ExpandoObject)
    {
        if (((IDictionary<string, object>)obj).ContainsKey(name))
            return ((IDictionary<string, object>)obj)[name] != null;
        return false;
    }
    if (obj is IDictionary<string, object> dict1)
    {
        if (dict1.ContainsKey(name))
            return dict1[name] != null;
        return false;
    }
    if (obj is IDictionary<string, JToken> dict2)
    {
        if (dict2.ContainsKey(name))
            return (dict2[name].Type != JTokenType.Null && dict2[name].Type != JTokenType.Undefined);
        return false;
    }
    if (obj.GetType().GetProperty(name) != null)
        return obj.GetType().GetProperty(name).GetValue(obj) != null;
    return false;
}