通过string获取c#dynamic属性的值
我想访问一个string的dynamic
c#属性的值:
dynamic d = new { value1 = "some", value2 = "random", value3 = "value" };
如果我只有“value2”作为string,我怎样才能得到d.value2(“random”)的值? 在JavaScript中,我可以做d [“value2”]来访问值(“随机”),但我不知道如何用c#和reflection做到这一点。 我最近来的是这样的:
d.GetType().GetProperty("value2")
…但我不知道如何从中得到实际的价值。
一如既往,感谢您的帮助!
一旦你有你的PropertyInfo
(来自GetProperty
),你需要调用GetValue
并传入你想从中获取值的实例。 在你的情况下:
d.GetType().GetProperty("value2").GetValue(d, null);
public static object GetProperty(object target, string name) { var site = System.Runtime.CompilerServices.CallSite<Func<System.Runtime.CompilerServices.CallSite, object, object>>.Create(Microsoft.CSharp.RuntimeBinder.Binder.GetMember(0, name, target.GetType(), new[]{Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(0,null)})); return site.Target(site, target); }
将引用添加到Microsoft.CSharp。 也适用于dynamictypes和私有属性和字段。
编辑 :虽然这种方法的工作,从Microsoft.VisualBasic.dll程序集有几乎20倍的方法:
public static object GetProperty(object target, string name) { return Microsoft.VisualBasic.CompilerServices.Versioned.CallByName(target, name, CallType.Get); }
Dynamitey是一个开放源代码的PCL
库,让我们把它称为dynamic
关键字,但是使用一个string作为属性名称,而不是编译器为你做,而且它最终等于reflection速度 (这不是近乎的与使用dynamic关键字一样快,但这是由于dynamiccaching的额外开销,即编译器在其中进行静态caching)。
Dynamic.InvokeGet(d,"value2");
很多时候,当你要求一个dynamic的对象,你会得到一个ExpandoObject(不是在上面的问题的匿名 – 但静态types的例子,但你提到JavaScript和我select的JSONparsing器JsonFx,一个,生成ExpandoObjects)。
如果您的dynamic实际上是一个ExpandoObject,则可以通过将其转换为IDictionary来避免reflection,如http://msdn.microsoft.com/en-gb/library/system.dynamic.expandoobject.aspx中所述; 。
一旦你投到了IDictionary,你可以访问有用的方法,如.Item和.ContainsKey
获取适用于任何types(包括dynamic
和ExpandoObject
)的属性的setter
和getter
的最简单方法是使用FastMember
,它也是最快的方法(它使用Emit)。
您可以获取基于给定types的TypeAccessor
或基于给定types的实例的ObjectAccessor
。
例:
var staticData = new Test { Id = 1, Name = "France" }; var objAccessor = ObjectAccessor.Create(staticData); objAccessor["Id"].Should().Be(1); objAccessor["Name"].Should().Be("France"); var anonymous = new { Id = 2, Name = "Hilton" }; objAccessor = ObjectAccessor.Create(anonymous); objAccessor["Id"].Should().Be(2); objAccessor["Name"].Should().Be("Hilton"); dynamic expando = new ExpandoObject(); expando.Id = 3; expando.Name = "Monica"; objAccessor = ObjectAccessor.Create(expando); objAccessor["Id"].Should().Be(3); objAccessor["Name"].Should().Be("Monica"); var typeAccessor = TypeAccessor.Create(staticData.GetType()); typeAccessor[staticData, "Id"].Should().Be(1); typeAccessor[staticData, "Name"].Should().Be("France"); typeAccessor = TypeAccessor.Create(anonymous.GetType()); typeAccessor[anonymous, "Id"].Should().Be(2); typeAccessor[anonymous, "Name"].Should().Be("Hilton"); typeAccessor = TypeAccessor.Create(expando.GetType()); ((int)typeAccessor[expando, "Id"]).Should().Be(3); ((string)typeAccessor[expando, "Name"]).Should().Be("Monica");
d.GetType()的getProperty( “值2”)
返回一个PropertyInfo对象。
那么呢
propertyInfo.GetValue(d)
这是我得到一个属性价值的方式:
public dynamic Post(dynamic value) { try { if (value != null) { var valorCampos = ""; foreach (Newtonsoft.Json.Linq.JProperty item in value) { if (item.Name == "valorCampo")//property name valorCampos = item.Value.ToString(); } } } catch (Exception ex) { } }
GetProperty / GetValue不适用于Json数据,它总是生成一个空的exception,但是,你可以尝试这种方法:
使用JsonConvert序列化您的对象:
var z = Newtonsoft.Json.JsonConvert.DeserializeObject(Convert.ToString(request));
然后直接访问它将其重新转换回string:
var pn = (string)z["DynamicFieldName"];
它可以直接应用Convert.ToString(request)[“DynamicFieldName”],但我没有testing。