繁体   English   中英

通过字符串从 C# 动态 object 获取属性值(反射?)

[英]Get property value from C# dynamic object by string (reflection?)

想象一下,我有一个动态变量:

dynamic d = *something*

现在,我从字符串数组中为d创建属性:

string[] strarray = { 'property1','property2',..... }

我事先不知道物业名称。

在代码中,一旦创建了d并从数据库中提取了 strarray,我可以获得这些值吗?

我想得到d.property1, d.property2

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

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

var nameOfProperty = "property1";
var propertyInfo = myObject.GetType().GetProperty(nameOfProperty);
var value = propertyInfo.GetValue(myObject, null);

如果myObject的类型不包含具有此名称的公共属性, GetProperty将返回null


编辑:如果对象不是“常规”对象而是实现IDynamicMetaObjectProvider的对象,则此方法将不起作用。 请改为查看此问题:

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

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);
}

希望这会对您有所帮助:

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);
    }
}

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

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
 }
string json = w.JSON;

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

DynamicJsonConverter.DynamicJsonObject obj = 
      (DynamicJsonConverter.DynamicJsonObject)serializer.Deserialize(json, typeof(object));

现在obj._Dictionary包含一个字典。 完美的!

此代码必须与Deserialize JSON into C# 动态对象结合使用吗? + 在代码中将_dictionary 变量从“私有只读”变为公共

你看到ExpandoObject类了吗?

直接来自MSDN 描述:“表示一个对象,其成员可以在运行时动态添加和删除。”

有了它,您可以编写如下代码:

dynamic employee = new ExpandoObject();
employee.Name = "John Smith";
((IDictionary<String, Object>)employee).Remove("Name");

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

    foreach (JProperty property in d)
    {
        DoSomething(property.Name, property.Value);
    }

使用属性(字符串)从动态对象中获取值数据。

var nameOfProperty = "chairs";
var propertyInfo = model.assets.GetType().GetField(nameOfProperty).GetValue(model.assets);

我知道这是一个老问题,但我想分享我的解决方案:这对动态和“非动态”数据都适用:

var _RowData = mydata[RowIndex]; //<- Whole Row of Data
//Locate and Load the Field Property by Name:
var propertyInfo = System.ComponentModel.TypeDescriptor.
    GetProperties((object)_RowData ).   
    Find("field_name", true);

string FieldName = propertyInfo.Name;
object FieldValue = propertyInfo.GetValue(_dataRow);

使用 Newtonsoft.Json 对从 JSON 文件转换的动态数据进行测试。

认为这可能对将来的某人有所帮助。

如果您已经知道属性名称,则可以执行以下操作:

[HttpPost]
[Route("myRoute")]
public object SomeApiControllerMethod([FromBody] dynamic args){
   var stringValue = args.MyPropertyName.ToString();
   //do something with the string value.  If this is an int, we can int.Parse it, or if it's a string, we can just use it directly.
   //some more code here....
   return stringValue;
}

假设您在服务 result.Value 中有匿名类型,具有类 errorCode 和属性 ErrorMessage,并且需要获取 ErrorMessage 的值,可以使用动态这样的单行方式获取它:

var resVal = (动态)result.Value; var errMsg = resVal.GetType().GetProperty("errorCode").GetValue(resVal, null).ErrorMessage;

您可以使用“ dynamicObject.PropertyName.Value ”直接获取动态属性的值。

示例

d.property11.Value

你可以这样尝试:

d?.property1 , d?.property2

我已经对其进行了测试并使用了 .netcore 2.1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM