我想用一个字符串访问一个动态c#属性的值:

动态d = new {value1 = "some", value2 = "random", value3 = "value"};

如果我只有“value2”作为字符串,我如何才能得到d.value2(“random”)的值?在javascript中,我可以做d["value2"]来访问值("random"),但我不确定如何用c#和反射来做到这一点。我最接近的说法是:

“value2”d.GetType () . getproperty()……但我不知道如何从中获得实际价值。

一如既往,谢谢你的帮助!


当前回答

从动态文档中获取属性 当.GetType()返回null时,尝试这样做:

var keyValuePairs = ((System.Collections.Generic.IDictionary<string, object>)doc);
var val = keyValuePairs["propertyName"].ToObject<YourModel>;

其他回答

GetProperty/GetValue对Json数据不起作用,它总是生成一个空异常,但是,你可以尝试这种方法:

使用JsonConvert序列化你的对象:

var z = Newtonsoft.Json.JsonConvert.DeserializeObject(Convert.ToString(request));

然后直接访问它,将其转换回string:

var pn = (string)z["DynamicFieldName"];

它可以直接应用Convert.ToString(request)["DynamicFieldName"],但我还没有测试。

一些解决方案不是工作的valuekind对象,我从一个json字符串获得的,也许是因为我没有一个具体的类型在我的代码,类似于对象,我将从json字符串获得,所以我是如何去做的

JsonElement myObject = System.Text.Json.JsonSerializer.Deserialize<JsonElement>(jsonStringRepresentationOfMyObject);

/*In this case I know that there is a property with 
the name Code, otherwise use TryGetProperty. This will 
still return a JsonElement*/

JsonElement propertyCode = myObject.GetProperty("Code");
        
/*Now with the JsonElement that represents the property, 
you can use several methods to retrieve the actual value, 
in this case I know that the value in the property is a string, 
so I use the GetString method on the object. If I knew the value 
was a double, then I would use the GetDouble() method on the object*/

string code = propertyCode.GetString();

这对我很有用

为一个适用于任何类型的属性(包括dynamic和ExpandoObject)获取setter和getter的最简单方法是使用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");

很多时候,当您请求一个动态对象时,您会得到一个ExpandoObject(不是在上面问题的匿名但静态类型的示例中,但您提到了JavaScript和我选择的JSON解析器JsonFx,例如,生成ExpandoObject)。

如果您的动态实际上是一个ExpandoObject,您可以通过将其强制转换为IDictionary来避免反射,如http://msdn.microsoft.com/en-gb/library/system.dynamic.expandoobject.aspx所述。

一旦转换为IDictionary,就可以访问有用的方法,如.Item和.ContainsKey

从动态文档中获取属性 当.GetType()返回null时,尝试这样做:

var keyValuePairs = ((System.Collections.Generic.IDictionary<string, object>)doc);
var val = keyValuePairs["propertyName"].ToObject<YourModel>;