在Teddy的 DynamicMethodProxyFactory組件中,提供了一種調用非公有方法的機制。本質上,通過這 個組件是可以實現任意的公有和非公有屬性的讀寫操作(屬性本質上可以通過它的get/set方法以方法的 形式訪問)。而且性能會比反射提高3 - 4數量級。但是如果我們希望訪問某些非公有字段時,那我們還 是無法使用DynamicMethodProxyFactory組件,還是需要使用反射。
這時,NonPublicPropertyProxy就派上用場了。這個組件是我根據NBear.Mapping中對屬性的讀寫原理 抽取出來的。由於它仍然是基於IL和CodeGenerator,因此在性能仍然具備DynamicMethodProxyFactory的 特點。
該組件實現的功能,通過代理非常簡單的支持對任意實例屬性(Property)/字段(Field)的讀寫,支持 任意靜態字段的讀寫。但不支持靜態屬性的讀寫(對靜態屬性的讀寫還得通過 DynamicMethodProxyFactory)。
由於該組件會動態組織IL代理函數,因此在首次獲取代理方法時,會需要一些性能損失 (DynamicMethodProxyFactory也是如此)。因此如果只需一次讀寫非公有屬性/字段時,還是盡可能選擇 其它方式,比如反射。
使用演示:
code 1 設置私有字段值
1 User user = 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
8 string name = "abu";
9 nameSetter(user, name);
10
11 int i = 995006;
12 idSetter(user, i);
13
14 statusSetter(user, UserStatus.Admin);
15
16 List<string> children = new List<string>();
17 childrenSetter(user, children);
18
19 staticFieldSetter(null, 100);
20