我有一个匿名类型对象,我从方法接收动态 我想检查该对象上存在的属性。
....
var settings = new {
Filename="temp.txt",
Size=10
}
...
function void Settings(dynamic settings) {
var exists = IsSettingExist(settings,"Filename")
}
我如何实施IsSettingExist?
答案 0 :(得分:116)
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
答案 1 :(得分:30)
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;
}
答案 2 :(得分:12)
如果您可以控制创建/传递设置对象,我建议使用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 :(得分:3)
这对我有用 - :
public static bool IsPropertyExist(dynamic dynamicObj, string property)
{
try
{
var value=dynamicObj[property].Value;
return true;
}
catch (RuntimeBinderException)
{
return false;
}
}
答案 4 :(得分:3)
合并并修复来自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;
}
答案 5 :(得分:2)
使用反射,这是我使用的功能:
public static bool doesPropertyExist(dynamic obj, string property)
{
return ((Type)obj.GetType()).GetProperties().Where(p => p.Name.Equals(property)).Any();
}
然后..
if (doesPropertyExist(myDynamicObject, "myProperty")){
// ...
}
答案 6 :(得分:1)
上述解决方案均不适用于来自dynamic
的{{1}},但我通过更改抛出的异常类型(Json
设法转换为Try catch
(@ user3359453)而不是KeyNotFoundException
)进入实际有用的东西......
RuntimeBinderException
希望这可以节省你一些时间。
答案 7 :(得分:1)
如果有人需要处理来自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;
}
答案 8 :(得分:1)
我不确定这些答案为何如此复杂,请尝试:
dynamic settings = new
{
Filename = "temp.txt",
Size = 10
};
string fileName = settings.Filename;
var fileNameExists = fileName != null;
答案 9 :(得分:1)
我遇到了动态是 Newtonsoft.Json.Linq.JObject
而不是 IDictionary
我添加了额外的 if 并且它有效。
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;
}
}
答案 10 :(得分:0)
这适用于匿名类型,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;
}
答案 11 :(得分:0)
要扩展@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;
}
答案 12 :(得分:0)
这也适用于 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;
}
答案 13 :(得分:0)
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
时间:59.5907507s 内存:403680
拥有属性
时间:30.8231781s 内存:14968
IsPropertyExist
时间:39.6179575s 内存:97000
IsPropertyExistBinderException throw find
属性存在
时间:56.009761s 内存:13464
PropertyExistsJToken
时间:61.6146953s 内存:15952