2011-12-25 72 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); 
    }