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

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

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

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

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


当前回答

类似于接受的答案,您也可以尝试GetField而不是GetProperty。

d.GetType().GetField(“value2”).获取值(d);

这取决于实际的Type是如何实现的,当GetProperty()不起作用时,它可以工作,甚至可以更快。

其他回答

在Newtonsoft.Json.JsonConvert.DeserializeObject中使用dynamic:

// Get JSON string of object
var obj = new { value1 = "some", value2 = "random", value3 = "value" };
var jsonString = JsonConvert.SerializeObject(obj);

// Use dynamic with JsonConvert.DeserializeObject
dynamic d = JsonConvert.DeserializeObject(jsonString);

// output = "some"
Console.WriteLine(d["value1"]);

示例: https://dotnetfiddle.net/XGBLU1

为一个适用于任何类型的属性(包括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");

一旦你有了你的PropertyInfo(从GetProperty),你需要调用GetValue并传递你想要从中获取值的实例。在你的情况下:

d.GetType().GetProperty("value2").GetValue(d, null);

Dynamitey是一个开源的。net std库,让你像动态关键字一样调用它,但是使用一个字符串作为属性名,而不是编译器为你做它,它最终等于反射速度(这几乎不如使用动态关键字快,但这是由于动态缓存的额外开销,其中编译器静态缓存)。

Dynamic.InvokeGet(d,"value2");

这是我得到一个动态的属性值的方法:

    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)
        {

        }


    }