在Teddy的 DynamicMethodProxyFactory组件中,提供了一种调用非公有方法的机制。本质上,通过这个组件是可以实现任意的公有和非公有属性的读写操作(属性本质上可以通过它的get/set方法以方法的形式访问)。而且性能会比反射提高3 - 4数量级。但是如果我们希望访问某些非公有字段时,那我们还是无法使用DynamicMethodProxyFactory组件,还是需要使用反射。
这时,NonPublicPropertyProxy就派上用场了。这个组件是我根据NBear.Mapping中对属性的读写原理抽取出来的。由于它仍然是基于IL和CodeGenerator,因此在性能仍然具备DynamicMethodProxyFactory的特点。
该组件实现的功能,通过代理非常简单的支持对任意实例属性(Property)/字段(Field)的读写,支持任意静态字段的读写。但不支持静态属性的读写(对静态属性的读写还得通过DynamicMethodProxyFactory)。
由于该组件会动态组织IL代理函数,因此在首次获取代理方法时,会需要一些性能损失(DynamicMethodProxyFactory也是如此)。因此如果只需一次读写非公有属性/字段时,还是尽可能选择其它方式,比如反射。
使用演示:
code 1 设置私有字段值
CODE 2 读取私有字段值
性能:
写属性/字段时,与反射的时间对比:
次数(Ticks) DynamicPropertySetter|ReflectPeropertySetter|
1 111439(111439.00) |2822(2822.00) |
101 2133(21.33) |6365(63.65) |
201 4116(41.16) |6451(64.51) |
301 2661(26.61) |6256(62.56) |
401 2165(21.65) |16358(163.58) |
501 3506(35.06) |6948(69.48) |
601 2119(21.19) |6232(62.32) |
701 2636(26.36) |6260(62.60) |
801 4607(46.07) |8072(80.72) |
901 2085(20.85) |6269(62.69) |
1001 2136(21.36) |6780(67.80) |
1101 2040(20.40) |6256(62.56) |
1201 2080(20.80) |6997(69.97) |
读属性/字段时,与反射的时间对比:
次数(Ticks) DynamicPropertyGetter|ReflectPeropertyGetter|
1 21324(21324.00) |2834(2834.00) |
101 2096(20.96) |5719(57.19) |
201 2077(20.77) |6130(61.30) |
301 5368(53.68) |5729(57.29) |
401 2091(20.91) |5528(55.28) |
501 2086(20.86) |6077(60.77) |
601 2101(21.01) |5591(55.91) |
701 2094(20.94) |5979(59.79) |
801 2164(21.64) |5780(57.80) |
901 2137(21.37) |5463(54.63) |
1001 2071(20.71) |5523(55.23) |
1101 2096(20.96) |5576(55.76) |
1201 2083(20.83) |5566(55.66) |
1301 2135(21.35) |5827(58.27) |
1401 1996(19.96) |5457(54.57) |
1501 2518(25.18) |5513(55.13) |
1601 2007(20.07) |5537(55.37) |
1701 2014(20.14) |6128(61.28) |