在Teddy的 DynamicMethodProxyFactory组件中,提供了一种调用非公有方法的机制。本质上,通过这个组件是可以实现任意的公有和非公有属性的读写操作(属性本质上可以通过它的get/set方法以方法的形式访问)。而且性能会比反射提高3 - 4数量级。但是如果我们希望访问某些非公有字段时,那我们还是无法使用DynamicMethodProxyFactory组件,还是需要使用反射。$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
这时,NonPublicPropertyProxy就派上用场了。这个组件是我根据NBear.Mapping中对属性的读写原理抽取出来的。由于它仍然是基于IL和CodeGenerator,因此在性能仍然具备DynamicMethodProxyFactory的特点。$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
该组件实现的功能,通过代理非常简单的支持对任意实例属性(Property)/字段(Field)的读写,支持任意静态字段的读写。但不支持静态属性的读写(对静态属性的读写还得通过DynamicMethodProxyFactory)。$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
由于该组件会动态组织IL代理函数,因此在首次获取代理方法时,会需要一些性能损失(DynamicMethodProxyFactory也是如此)。因此如果只需一次读写非公有属性/字段时,还是尽可能选择其它方式,比如反射。$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
使用演示:$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
code 1 设置私有字段值$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
1 User user =$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
new User(); 2 NonPropertySetterDelegate nameSetter = NonPublicPropertyProxyFactory.GetPropertySetter(typeof(User), "name"); 3 NonPropertySetterDelegate idSetter = NonPublicPropertyProxyFactory.GetPropertySetter(typeof(User), "id"); 4 NonPropertySetterDelegate statusSetter = NonPublicPropertyProxyFactory.GetPropertySetter(typeof(User), "status"); 5 NonPropertySetterDelegate childrenSetter = NonPublicPropertyProxyFactory.GetPropertySetter(typeof(User), "Children"); 6 NonPropertySetterDelegate staticFieldSetter = NonPublicPropertyProxyFactory.GetPropertySetter(typeof(User), "staticValue"); 7 $©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
8 $©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
string name =$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
"abu"; 9 nameSetter(user, name);10 $©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
11 $©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
int i =$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
995006;12 idSetter(user, i);13 $©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
14 statusSetter(user, UserStatus.Admin);15 $©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
16 List<string> children =$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
new List<string>();17 childrenSetter(user, children);18 $©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
19 staticFieldSetter(null, 100);20 $©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
CODE 2 读取私有字段值$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
User user =$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
new User(995006, "abu", UserStatus.Admin);user.Children =$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
new List<string>();NonPropertyGetterDelegate nameGetter = NonPublicPropertyProxyFactory.GetPropertyGetter(typeof(User), "name");NonPropertyGetterDelegate idGetter = NonPublicPropertyProxyFactory.GetPropertyGetter(typeof(User), "id");NonPropertyGetterDelegate statusGetter = NonPublicPropertyProxyFactory.GetPropertyGetter(typeof(User), "status");NonPropertyGetterDelegate childrenGetter = NonPublicPropertyProxyFactory.GetPropertyGetter(typeof(User), "Children");NonPropertyGetterDelegate staticFieldGetter = NonPublicPropertyProxyFactory.GetPropertyGetter(typeof(User), "staticValue");int id = (int)idGetter(user);string name = nameGetter(user).ToString();UserStatus status = (UserStatus)statusGetter(user);List<string> children = (List<string>)childrenGetter(user);int staticFieldValue = (int)staticFieldGetter(null);$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
性能:$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
写属性/字段时,与反射的时间对比:$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
次数(Ticks)    DynamicPropertySetter|ReflectPeropertySetter|$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
1      111439(111439.00)  |2822(2822.00)      |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
101    2133(21.33)        |6365(63.65)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
201    4116(41.16)        |6451(64.51)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
301    2661(26.61)        |6256(62.56)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
401    2165(21.65)        |16358(163.58)      |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
501    3506(35.06)        |6948(69.48)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
601    2119(21.19)        |6232(62.32)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
701    2636(26.36)        |6260(62.60)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
801    4607(46.07)        |8072(80.72)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
901    2085(20.85)        |6269(62.69)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
1001    2136(21.36)        |6780(67.80)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
1101    2040(20.40)        |6256(62.56)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
1201    2080(20.80)        |6997(69.97)        | $©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
读属性/字段时,与反射的时间对比: $©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
次数(Ticks)    DynamicPropertyGetter|ReflectPeropertyGetter|$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
1      21324(21324.00)    |2834(2834.00)      |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
101    2096(20.96)        |5719(57.19)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
201    2077(20.77)        |6130(61.30)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
301    5368(53.68)        |5729(57.29)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
401    2091(20.91)        |5528(55.28)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
501    2086(20.86)        |6077(60.77)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
601    2101(21.01)        |5591(55.91)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
701    2094(20.94)        |5979(59.79)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
801    2164(21.64)        |5780(57.80)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
901    2137(21.37)        |5463(54.63)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
1001    2071(20.71)        |5523(55.23)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
1101    2096(20.96)        |5576(55.76)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
1201    2083(20.83)        |5566(55.66)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
1301    2135(21.35)        |5827(58.27)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
1401    1996(19.96)        |5457(54.57)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
1501    2518(25.18)        |5513(55.13)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
1601    2007(20.07)        |5537(55.37)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
1701    2014(20.14)        |6128(61.28)        |$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf
源码和示例下载$©=Çø‘ŠÇwww.netcsharp.cn5ÍÙëÜ\êOòf