C# DynamicObject dynamic properties

笑着哭i 提交于 2019-12-03 00:19:56

Although the c# compiler is translating dynamic keyword usage to invocation with the dlr using a string name, those Apis are difficult to use directly without the compilers help. The open source framework Dynamitey (available through nuget as a PCL library) encapsulates the dlr API, to make it easy so that you can just call Impromptu.InvokeSet(target,name,value).

using Dynamitey;
...

dynamic o = MyNewObject();

Dynamic.InvokeSet(o,"Age" ,87); 
Dynamic.InvokeSet(o,"Names" ,"Same);   

Getters and Setters are the least complicated to use the actual Microsft API directly, so if you don't want to use the 3rd party framework going to the source is an option too.

using Microsoft.CSharp.RuntimeBinder;
using System.Runtime.CompilerServices;
...

dynamic o = MyNewObject();
var binder = Binder.SetMember(CSharpBinderFlags.None,
                   "Age",
                   typeof(object),
                   new List<CSharpArgumentInfo>{
                           CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                           CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
                                               });

  var callsite = CallSite<Func<CallSite, object, object, object>>.Create(binder);

  callsite.Target(callsite,o,87);

  var binder2 =Binder.SetMember(CSharpBinderFlags.None,
                   "Name",
                   typeof(object),
                   new List<CSharpArgumentInfo>{
                           CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null),
                           CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)
                                               });
  var callsite2 = CallSite<Func<CallSite, object, object, object>>.Create(binder2);

  callsite2.Target(callsite2,o,"Sam");

But the above assumes I know the properties (e.g. Age, Name) at compile time.

Suppose I don't know what they will be until run time.

Then the dynamic typing in C# 4 doesn't really help you at all, and you might as well just use Dictionary<string, object>.

Rather than assume that dynamic is the answer, I suggest you take a close look at your requirements, and work out what you're really trying to achieve. Once you've got a well-specified set of requirements, it's going to be easier to implement them.

You may find that you just need to make MyObject also implement IDictionary<string, object> like ExpandoObject does... although the problem there is that if you want to derive other classes from MyObject and have their properties exposed via the dictionary too, that's going to be trickier.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!