2011-12-25 25 views
54

假设我有一个动态变量(反射):现在获得通过字符串从C#动态对象的属性值

​​

东西创建属性d我有另一方面从字符串array:

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

我不知道属性名称提前。

如何在代码中创建d,并从数据库中提取strarray,我可以获取值吗?我想得到d.property1 , d.property2

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

+1

'something'是一个'IDynamicMetaObjectProvider'吗? – SLaks 2011-12-25 21:00:53

+0

在调试器中检查'something'的运行时类型并查看其公共成员。 – SLaks 2011-12-26 00:03:08

+1

你可以检查'd.GetType()在运行时给你什么吗? – 2011-12-26 01:29:21

回答

77

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

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

GetProperty将返回null如果myObject类型不包含公共财产与这个名字。


编辑:如果对象是不是“规则”的对象,但实施IDynamicMetaObjectProvider的东西,这种做法是行不通的。请看看这个问题,而不是:

+0

不幸的是它不工作: object obj = serializer.Deserialize(json, typeof(object)); var propertyInfo = obj.GetType().GetProperty("H3"); var value = propertyInfo.GetValue(obj, null); 的PropertyInfo为空,则第三线抛出异常。 – 2011-12-25 21:16:55

+0

@ sergata.NETLTD:但'var value = obj.H3'会起作用吗?你能证实吗? – Heinzi 2011-12-25 21:23:03

+0

是的,它会工作。 这个作品: dynamic obj = serializer.Deserialize(json,typeof(object)); var value = obj.H3; 值包含正确的值。问题是:我不知道H3是属性名称。属性名称来自数据库。 感谢您的帮助。 – 2011-12-25 21:32:27

17

这会给你在你的动态变量定义的所有属性名称和值。

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

这对我来说很好,我无法实现动态类型,谢谢 – 2016-04-05 13:30:37

+0

只有当d是静态类型时才有效。如果D是一个IDynamicMetaObjectProvider(如JObject),它会给你错误的属性。 例如,如果d = obj,那么它不会返回'x',它将返回JObject上的原始属性。 JObject obj = JObject。FromObject(新的 { x = 123 });你能解释这个代码吗? – 2017-04-19 22:51:00

5
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# dynamic object? +使从“私人只读”的_dictionary变量市民代码有

18

希望这会帮助你:

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

? – Ewerton 2017-09-29 14:46:35

+0

@Ewerton这已经有一段时间了,但我看到它使用* System.Linq.Expressions *将动态获取器绑定到调用站点,并将编译保留为* LambdaExpression *。我不知道我是否从反编译的代码或其他地方获得了这个。 – IllidanS4 2017-09-29 15:19:13

2

你有没有见ExpandoObject类?

直接从MSDN description:“表示其成员可以在运行时动态添加和删除的对象。”

有了它,你可以这样写代码:

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

属性名称不知道,所以这不起作用。 – user3285954 2018-02-03 17:12:12

+0

代码工作(我在Visual Studio中检查过),因为员工实例是ExpandoObject,所以它可能在运行时添加和删除属性(如何解释为MS官方文档)。这段代码完成了这个问题。 – ADIMO 2018-02-13 09:39:57

0

想这可能帮助别人的未来。

如果您知道属性名称已经,你可以这样做以下:

[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; 
} 
+0

属性名称未知。 – user3285954 2018-02-03 17:10:39

0

IF d是由Newtonsoft创造了你可以用它来读取属性名称和值:

foreach (JProperty property in d) 
    { 
     DoSomething(property.Name, property.Value); 
    } 
相关问题