zl程序教程

您现在的位置是:首页 >  后端

当前栏目

C#Dynamic之:ExpandoObject,DynamicObject,DynamicMetaOb的应用(上)

c#应用 Dynamic
2023-06-13 09:14:53 时间

ExpandoObject:表示一个对象,该对象包含可在运行时动态添加和移除的成员。

复制代码代码如下:

dynamicdynEO=newExpandoObject();
dynEO.number=10;
dynEO.Increment=newAction(()=>{dynEO.number++;});

Console.WriteLine(dynEO.number);
dynEO.Increment();
Console.WriteLine(dynEO.number);


dynEO.number中number是动态添加属性。

dynEO.Increment中Increment是动态添加的Action委托。

枚举ExpandoObject的所有成员:

复制代码代码如下:

foreach(varpropertyin(IDictionary<String,Object>)dynEO)
{
    Console.WriteLine(property.Key+":"+property.Value);
}

结果如下:

接收属性更改的通知:

复制代码代码如下:
staticvoidMain(string[]args)
{
  ………
   ((INotifyPropertyChanged)dynEO).PropertyChanged+=newPropertyChangedEventHandler(Program_PropertyChanged);
   dynEO.Name="changed";
   dynEO.Name="another";

   Console.ReadLine();
}

staticvoidProgram_PropertyChanged(objectsender,PropertyChangedEventArgse)
{
   Console.WriteLine("属性{0}已更改",e.PropertyName);
}

结果:

System.Dynamic.DynamicObject:提供用于指定运行时的动态行为的基类

新建类DynamicProduct,基本和Product类似:

可以看到继承了DynamicObject后,可以override一大堆TryXXX的方法了。

重点需要了解的是:

假设sampleObject就是dynamicObject

TryGetMember

在调用intnumber=sampleObject.Number.时使用

TrySetMember

在调用sampleObject.Number=number时使用

TryInvoke

在调用sampleObject(100)时使用

TryInvokeMember

在调用sampleObject.someMethod(100)时使用

完整的代码如下:

复制代码代码如下:
classDynamicProduct:DynamicObject
{
   publicstringname;
   publicintId{get;set;}

   publicvoidShowProduct()
   {
       Console.WriteLine("Id={0},Name={1}",Id,name);
   }

   #regionOverrideDynamicObject的方法

   publicoverrideIEnumerable<string>GetDynamicMemberNames()
   {
       returnbase.GetDynamicMemberNames();
   }

   publicoverrideboolTryGetMember(GetMemberBinderbinder,outobjectresult)
   {
       Console.WriteLine("TryGetMember被调用了,Name:{0}",binder.Name);
       returnbase.TryGetMember(binder,outresult);
   }

   publicoverrideboolTrySetMember(SetMemberBinderbinder,objectvalue)
   {
       Console.WriteLine("TrySetMember被调用了,Name:{0}",binder.Name);
       returnbase.TrySetMember(binder,value);
   }

   publicoverrideboolTryInvoke(InvokeBinderbinder,object[]args,outobjectresult)
   {
       Console.WriteLine("TryInvoke被调用了");
       returnbase.TryInvoke(binder,args,outresult);
   }

   publicoverrideboolTryInvokeMember(InvokeMemberBinderbinder,object[]args,outobjectresult)
   {
       Console.WriteLine("TryInvokeMember被调用了,Name:{0}",binder.Name);
       returnbase.TryInvokeMember(binder,args,outresult);
   }

   #endregion
}


Main函数代码如下:
复制代码代码如下:
staticvoidMain(string[]args)
{
   dynamicdynProduct=newDynamicProduct();

   dynProduct.name="n1";//调用TrySetMember方法
   dynProduct.Id=1;
   dynProduct.Id=dynProduct.Id+3;
   dynProduct.ShowProduct();

   Console.ReadLine();
}


结果如下:

.csharpcode,.csharpcodepre{font-size:small;color:black;font-family:consolas,"CourierNew",courier,monospace;background-color:#ffffff;/*white-space:pre;*/}.csharpcodepre{margin:0em;}.csharpcode.rem{color:#008000;}.csharpcode.kwrd{color:#0000ff;}.csharpcode.str{color:#006080;}.csharpcode.op{color:#0000c0;}.csharpcode.preproc{color:#cc6633;}.csharpcode.asp{background-color:#ffff00;}.csharpcode.html{color:#800000;}.csharpcode.attr{color:#ff0000;}.csharpcode.alt{background-color:#f4f4f4;width:100%;margin:0em;}.csharpcode.lnum{color:#606060;}

理论上来说,应该输出:

TrySetMember         :设置name字段

TrySetMember         :设置Id属性

TryGetMember         :获取Id属性

TrySetMember         :设置Id属性

TryInvokeMember     :调用ShowProduct方法

Id=4,Name=n1

为什么TryXXX方法没有被调用??

下篇将解释这个问题,请持续关注..