我想dynamic用字符串访问c#属性的值:
dynamic d = new { value1 = "some", value2 = "random", value3 = "value" };
如果我只将"value2"作为字符串,我怎样才能获得d.value2("random")的值?在javascript中,我可以使用d ["value2"]来访问值("随机"),但我不知道如何使用c#和反射来执行此操作.我最接近的是:
d.GetType().GetProperty("value2") ......但我不知道如何从中获得实际价值.
一如既往,感谢您的帮助!
Ada*_*son 211
获得PropertyInfo(from GetProperty)之后,需要调用GetValue并传入要从中获取值的实例.在你的情况下:
d.GetType().GetProperty("value2").GetValue(d, null);
Run Code Online (Sandbox Code Playgroud)
Ill*_*ack 39
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);
}
Run Code Online (Sandbox Code Playgroud)
添加对Microsoft.CSharp的引用.也适用于动态类型和私有属性和字段.
编辑:虽然这种方法有效,但Microsoft.VisualBasic.dll程序集的方法快了近20倍:
public static object GetProperty(object target, string name)
{
return Microsoft.VisualBasic.CompilerServices.Versioned.CallByName(target, name, CallType.Get);
}
Run Code Online (Sandbox Code Playgroud)
jbt*_*ule 22
Dynamitey是一个开源.net std库,让你像dynamic关键字一样调用它,但是使用一个字符串作为属性名而不是编译器为你做的,它最终等于反射速度(这几乎没有那么快)使用动态关键字,但这是由于动态缓存的额外开销,编译器静态缓存).
Dynamic.InvokeGet(d,"value2");
Run Code Online (Sandbox Code Playgroud)
MaY*_*YaN 10
获取a setter和a getter属性的最简单方法,适用于任何类型,包括dynamic和ExpandoObject使用FastMember,这也是最快的方法(它使用Emit).
您可以TypeAccessor根据给定类型或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");
Run Code Online (Sandbox Code Playgroud)
小智 8
.GetType()要在return时从动态文档获取属性null,请尝试以下操作:
var keyValuePairs = ((System.Collections.Generic.IDictionary<string, object>)doc);
var val = keyValuePairs["propertyName"].ToObject<YourModel>;
Run Code Online (Sandbox Code Playgroud)
在你要求动态对象的大部分时间里,你得到一个ExpandoObject(不是上面的问题的匿名但静态类型的例子,但是你提到了JavaScript和我选择的JSON解析器JsonFx,生成一个,生成ExpandoObjects).
如果您的动态实际上是ExpandoObject,则可以通过将其转换为IDictionary来避免反射,如http://msdn.microsoft.com/en-gb/library/system.dynamic.expandoobject.aspx中所述.
一旦转换为IDictionary,您就可以访问有用的方法,如.Item和.ContainsKey
d.GetType().GetProperty("value2")
返回一个 PropertyInfo 对象。
那么做
propertyInfo.GetValue(d)
Run Code Online (Sandbox Code Playgroud)
小智 5
这是我获取动态属性值的方法:
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)
{
}
}
Run Code Online (Sandbox Code Playgroud)
GetProperty / GetValue不适用于Json数据,它始终生成null异常,但是,您可以尝试以下方法:
使用JsonConvert序列化您的对象:
var z = Newtonsoft.Json.JsonConvert.DeserializeObject(Convert.ToString(request));
Run Code Online (Sandbox Code Playgroud)
然后直接访问将其转换回字符串:
var pn = (string)z["DynamicFieldName"];
Run Code Online (Sandbox Code Playgroud)
它可能工作直施加Convert.ToString(请求)“DynamicFieldName”],但是我没有测试。