[英]How do I check if a property exists on a dynamic anonymous type in c#?
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 ?
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
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;
}
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 ....
}
This works for anonymous types, ExpandoObject
, Nancy.DynamicDictionary
or anything else that can be cast to IDictionary<string, object>
.这适用于匿名类型、 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;
}
Merging and fixing answers from Serj-TM and user3359453 so that it works with both ExpandoObject and DynamicJsonObject.合并和修复来自 Serj-TM 和 user3359453 的答案,以便它同时适用于 ExpandoObject 和 DynamicJsonObject。 This works for me.这对我有用。
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;
}
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;
}
}
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")){
// ...
}
None of the solutions above worked for dynamic
that comes from Json
, I however managed to transform one with Try catch
(by @user3359453) by changing exception type thrown ( KeyNotFoundException
instead of RuntimeBinderException
) into something that actually works...上面的解决方案都不适用于来自Json
dynamic
,但是我设法通过将抛出的异常类型( KeyNotFoundException
而不是RuntimeBinderException
)更改为实际工作的东西来使用Try catch
(由@user3359453 提供)转换一个...
public static bool HasProperty(dynamic obj, string name)
{
try
{
var value = obj[name];
return true;
}
catch (KeyNotFoundException)
{
return false;
}
}
Hope this saves you some time.希望这可以为您节省一些时间。
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;
}
I ran into the dynamic was Newtonsoft.Json.Linq.JObject
instead of IDictionary
我遇到的动态是Newtonsoft.Json.Linq.JObject
而不是IDictionary
I added and extra if and it works.我添加了额外的如果它有效。
public static bool PropertyExists(dynamic obj, string name)
{
if (obj == null) return false;
else if (obj is IDictionary<string, object> dict)
{
return dict.ContainsKey(name);
}
else if (obj is Newtonsoft.Json.Linq.JObject jObject)
{
return jObject.ContainsKey(name);
}
else
{
return obj.GetType().GetProperty(name) != null;
}
}
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;
}
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?
This works also for DynamicJsonObject:这也适用于 DynamicJsonObject:
public static bool PropertyExists(dynamic settings, string name)
{
if (settings is ExpandoObject)
return ((IDictionary<string, object>)settings).ContainsKey(name);
else if (settings is DynamicJsonObject)
return ((DynamicJsonObject)settings).GetDynamicMemberNames().Contains(name);
return settings.GetType().GetProperty(name) != null;
}
public static void Test()
{
int LOOP_LENGTH = 100000000;
{
long first_memory = GC.GetTotalMemory(true);
var stopWatch = Stopwatch.StartNew();
Console.WriteLine("doesPropertyExist");
dynamic testdo = new { A = 1, B = (string)null, C = "A" };
for (int i = 0; i < LOOP_LENGTH; i++)
{
if (!TestDynamic.doesPropertyExist(testdo, "A"))
{
Console.WriteLine("throw find");
break;
}
if (TestDynamic.doesPropertyExist(testdo, "ABC"))
{
Console.WriteLine("throw not find");
break;
}
}
stopWatch.Stop();
var last_memory = GC.GetTotalMemory(true);
Console.WriteLine($" Time:{stopWatch.Elapsed.TotalSeconds}s\t Memory:{last_memory - first_memory}");
}
{
long first_memory = GC.GetTotalMemory(true);
var stopWatch = Stopwatch.StartNew();
Console.WriteLine("HasProperty");
dynamic testdo = new { A = 1, B = (string)null, C = "A" };
for (int i = 0; i < LOOP_LENGTH; i++)
{
if (!TestDynamic.HasProperty(testdo, "A"))
{
Console.WriteLine("throw find");
break;
}
if (TestDynamic.HasProperty(testdo, "ABC"))
{
Console.WriteLine("throw not find");
break;
}
}
stopWatch.Stop();
var last_memory = GC.GetTotalMemory(true);
Console.WriteLine($" Time:{stopWatch.Elapsed.TotalSeconds}s\t Memory:{last_memory - first_memory}");
}
{
long first_memory = GC.GetTotalMemory(true);
var stopWatch = Stopwatch.StartNew();
Console.WriteLine("IsPropertyExist");
dynamic testdo = new { A = 1, B = (string)null, C = "A" };
for (int i = 0; i < LOOP_LENGTH; i++)
{
if (!TestDynamic.IsPropertyExist(testdo, "A"))
{
Console.WriteLine("throw find");
break;
}
if (TestDynamic.IsPropertyExist(testdo, "ABC"))
{
Console.WriteLine("throw not find");
break;
}
}
stopWatch.Stop();
var last_memory = GC.GetTotalMemory(true);
Console.WriteLine($" Time:{stopWatch.Elapsed.TotalSeconds}s\t Memory:{last_memory - first_memory}");
}
{
long first_memory = GC.GetTotalMemory(true);
var stopWatch = Stopwatch.StartNew();
Console.WriteLine("IsPropertyExistBinderException");
dynamic testdo = new { A = 1, B = (string)null, C = "A" };
for (int i = 0; i < LOOP_LENGTH; i++)
{
if (!TestDynamic.IsPropertyExistBinderException(testdo, "A"))
{
Console.WriteLine("throw find");
break;
}
if (TestDynamic.IsPropertyExistBinderException(testdo, "ABC"))
{
Console.WriteLine("throw not find");
break;
}
}
stopWatch.Stop();
var last_memory = GC.GetTotalMemory(true);
Console.WriteLine($" Time:{stopWatch.Elapsed.TotalSeconds}s\t Memory:{last_memory - first_memory}");
}
{
long first_memory = GC.GetTotalMemory(true);
var stopWatch = Stopwatch.StartNew();
Console.WriteLine("PropertyExists");
dynamic testdo = new { A = 1, B = (string)null, C = "A" };
for (int i = 0; i < LOOP_LENGTH; i++)
{
if (!TestDynamic.PropertyExists(testdo, "A"))
{
Console.WriteLine("throw find");
break;
}
if (TestDynamic.PropertyExists(testdo, "ABC"))
{
Console.WriteLine("throw not find");
break;
}
}
stopWatch.Stop();
var last_memory = GC.GetTotalMemory(true);
Console.WriteLine($" Time:{stopWatch.Elapsed.TotalSeconds}s\t Memory:{last_memory - first_memory}");
}
{
long first_memory = GC.GetTotalMemory(true);
var stopWatch = Stopwatch.StartNew();
Console.WriteLine("PropertyExistsJToken");
dynamic testdo = new { A = 1, B = (string)null, C = "A" };
for (int i = 0; i < LOOP_LENGTH; i++)
{
if (!TestDynamic.PropertyExistsJToken(testdo, "A"))
{
Console.WriteLine("throw find");
break;
}
if (TestDynamic.PropertyExistsJToken(testdo, "ABC"))
{
Console.WriteLine("throw not find");
break;
}
}
stopWatch.Stop();
var last_memory = GC.GetTotalMemory(true);
Console.WriteLine($" Time:{stopWatch.Elapsed.TotalSeconds}s\t Memory:{last_memory - first_memory}");
}
}
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;
}
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;
}
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;
}
// public static bool HasPropertyExist(dynamic settings, string name)
// {
// if (settings is System.Dynamic.ExpandoObject)
// return ((IDictionary<string, object>)settings).ContainsKey(name);
// if (settings is DynamicJsonObject)
// try
// {
// return settings[name] != null;
// }
// catch (KeyNotFoundException)
// {
// return false;
// }
// return settings.GetType().GetProperty(name) != null;
// }
public static bool IsPropertyExistBinderException(dynamic dynamicObj, string property)
{
try
{
var value = dynamicObj[property].Value;
return true;
}
catch (RuntimeBinderException)
{
return false;
}
}
public static bool HasPropertyFoundException(dynamic obj, string name)
{
try
{
var value = obj[name];
return true;
}
catch (KeyNotFoundException)
{
return false;
}
}
public static bool doesPropertyExist(dynamic obj, string property)
{
return ((Type)obj.GetType()).GetProperties().Where(p => p.Name.Equals(property)).Any();
}
public static bool PropertyExistsJToken(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;
}
// public static bool PropertyExistsJsonObject(dynamic settings, string name)
// {
// if (settings is ExpandoObject)
// return ((IDictionary<string, object>)settings).ContainsKey(name);
// else if (settings is DynamicJsonObject)
// return ((DynamicJsonObject)settings).GetDynamicMemberNames().Contains(name);
// return settings.GetType().GetProperty(name) != null;
// }
}
doesPropertyExist是否存在属性
Time:59.5907507s Memory:403680时间:59.5907507s 内存:403680
HasProperty有属性
Time:30.8231781s Memory:14968时间:30.8231781s 内存:14968
IsPropertyExist是否存在属性
Time:39.6179575s Memory:97000时间:39.6179575s 内存:97000
IsPropertyExistBinderException throw find IsPropertyExistBinderException 抛出 find
PropertyExists属性存在
Time:56.009761s Memory:13464时间:56.009761s 内存:13464
PropertyExistsJToken PropertyExistsJToken
Time:61.6146953s Memory:15952时间:61.6146953s 内存:15952
To save others some time and this answer covers a lot of the people Googling this question using Newtonstoft Json deserialization with dynamics:为了节省其他人的时间,这个答案涵盖了很多使用 Newtonstoft Json 反序列化动态搜索这个问题的人:
dynamic dynamicObject = JsonConvert.DeserializeObject<dynamic>(json);
if (IsContainsKey(dynamicObject, "searchText"))
searchText = dynamicObject.searchText;
bool IsContainsKey(dynamic newtonsoftDynamic, string propertyName) {
return (newtonsoftDynamic as JObject).ContainsKey(propertyName);
}
or just in code:或者只是在代码中:
JObject obj = dynamicObject as JObject;
string searchText = string.Empty;
if (obj.ContainsKey("searchText"))
searchText = obj.Value<string>("searchText");
no exceptions, proper handling via Newtonsoft but you can still use the dynamicObject.xxx for properties you know will always be there.没有例外,通过 Newtonsoft 进行正确处理,但您仍然可以将 dynamicObject.xxx 用于您知道将始终存在的属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.