从字符串中获取C#动态对象的属性值(反射?)

ser*_*LTD 68 c# reflection .net-4.0

假设我有一个动态变量:

dynamic d = *something*
Run Code Online (Sandbox Code Playgroud)

现在,有些东西d从字符串数组中创建了我拥有的属性:

string[] strarray = { 'property1','property2',..... }
Run Code Online (Sandbox Code Playgroud)

我事先不知道房产名称.

如何在代码d中创建一次并从数据库中提取strarray,我可以获取值吗?

我想得到d.property1 , d.property2.

我看到该对象有一个_dictionary包含键和值的内部字典,如何检索它们?

Hei*_*nzi 96

我不知道动态创建的对象是否有更优雅的方式,但使用普通的旧反射应该有效:

var nameOfProperty = "property1";
var propertyInfo = myObject.GetType().GetProperty(nameOfProperty);
var value = propertyInfo.GetValue(myObject, null);
Run Code Online (Sandbox Code Playgroud)

GetPropertynull如果类型myObject不包含具有此名称的公共属性,则返回.


编辑:如果对象不是"常规"对象但实现的东西IDynamicMetaObjectProvider,这种方法将无法正常工作.请改为看看这个问题:


Tom*_*ski 27

这将为您提供动态变量中定义的所有属性名称和值.

dynamic d = { // your code };
object o = d;
string[] propertyNames = o.GetType().GetProperties().Select(p => p.Name).ToArray();
foreach (var prop in propertyNames)
{
    object propValue = o.GetType().GetProperty(prop).GetValue(o, null);
}
Run Code Online (Sandbox Code Playgroud)

  • 这仅在 d 是静态类型时才有效。如果 D 是 IDynamicMetaObjectProvider,(例如 JObject),它将为您提供错误的属性。例如,如果 d = obj,则它不会返回 'x',而是返回 JObject 上的原始属性。JObject obj = JObject.FromObject(new { x = 123 }); (2认同)

Ill*_*ack 22

希望这会对你有所帮助:

public static object GetProperty(object o, string member)
{
    if(o == null) throw new ArgumentNullException("o");
    if(member == null) throw new ArgumentNullException("member");
    Type scope = o.GetType();
    IDynamicMetaObjectProvider provider = o as IDynamicMetaObjectProvider;
    if(provider != null)
    {
        ParameterExpression param = Expression.Parameter(typeof(object));
        DynamicMetaObject mobj = provider.GetMetaObject(param);
        GetMemberBinder binder = (GetMemberBinder)Microsoft.CSharp.RuntimeBinder.Binder.GetMember(0, member, scope, new CSharpArgumentInfo[]{CSharpArgumentInfo.Create(0, null)});
        DynamicMetaObject ret = mobj.BindGetMember(binder);
        BlockExpression final = Expression.Block(
            Expression.Label(CallSiteBinder.UpdateLabel),
            ret.Expression
        );
        LambdaExpression lambda = Expression.Lambda(final, param);
        Delegate del = lambda.Compile();
        return del.DynamicInvoke(o);
    }else{
        return o.GetType().GetProperty(member, BindingFlags.Public | BindingFlags.Instance).GetValue(o, null);
    }
}
Run Code Online (Sandbox Code Playgroud)


Ghe*_*wet 6

使用以下代码获取动态对象属性的名称和值。

dynamic d = new { Property1= "Value1", Property2= "Value2"};

var properties = d.GetType().GetProperties();
foreach (var property in properties)
{
    var PropertyName=property.Name; 
//You get "Property1" as a result

  var PropetyValue=d.GetType().GetProperty(property.Name).GetValue(d, null); 
//You get "Value1" as a result

// you can use the PropertyName and Value here
 }
Run Code Online (Sandbox Code Playgroud)

  • 仅当基础类型是普通对象时。它不适用于像“PSObject”这样的包装对象 (2认同)

ser*_*LTD 5

string json = w.JSON;

var serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new[] { new DynamicJsonConverter() });

DynamicJsonConverter.DynamicJsonObject obj = 
      (DynamicJsonConverter.DynamicJsonObject)serializer.Deserialize(json, typeof(object));
Run Code Online (Sandbox Code Playgroud)

现在obj._Dictionary包含一本字典.完善!

此代码必须与反序列化JSON一起使用 到C#动态对象中? +在那里的代码中将_dictionary变量从"private readonly"变为public


use*_*954 5

如果 d 是由 Newtonsoft 创建的,您可以使用它来读取属性名称和值:

    foreach (JProperty property in d)
    {
        DoSomething(property.Name, property.Value);
    }
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

172629 次

最近记录:

6 年,5 月 前