Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use ReflectionDynamicObject to optimize reflection on .NET platform

2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

In this article, the editor gives you a detailed introduction of "how to use ReflectionDynamicObject to optimize reflection in the .NET platform". The content is detailed, the steps are clear, and the details are handled properly. I hope this article "how to use ReflectionDynamicObject to optimize reflection on the .NET platform" can help you solve your doubts.

Based on the principle of encapsulation, the designers of API will hide some members (properties, fields, methods, etc.) to ensure robustness. But there is always a need for direct access to these private members.

In order to access a type of private member, in addition to changing the API design, you also use reflection technology:

Public class MyApi {public MyApi () {_ createdAt = DateTime.Now;} private DateTime _ createdAt; public int ShowTimes {get; private set;} public void ShowCreateTime () {Console.WriteLine (_ createdAt); ShowTimes++;}} void Main () {var api = new MyApi () Var field = api.GetType () .GetField ("_ createdAt", BindingFlags.NonPublic | BindingFlags.Instance); var value = field.GetValue (api); Console.WriteLine (value);}

This way of writing is not elegant:

The code is lengthy and troublesome to write. The implementation is relatively round, not very intuitive.

Based on "dynamic typing technology", the author explored a relatively elegant scheme to beautify the above code and named it ReflectionDynamicObject:

Void Main () {var api = new MyApi (); dynamic wrapper = ReflectionDynamicObject.Wrap (api); Console.WriteLine (wrapper._createdAt);}

In addition to supporting getting values, ReflectionDynamicObject also supports assignment:

Void Main () {var api = new MyApi (); dynamic wrapper = ReflectionDynamicObject.Wrap (api); wrapper._createdAt = new DateTime (2022, 2, 2, 22, 22, 22); api.ShowCreateTime ();}

In addition to fields, of course, operations on properties are also supported:

Void Main () {var api = new MyApi (); dynamic wrapper = ReflectionDynamicObject.Wrap (api); wrapper.ShowTimes = 100; Console.WriteLine (wraper.ShowTimes);}

In terms of support for attributes, ReflectionDynamicObject uses "fast reflection" technology to generate delegates from values and copy operations to optimize performance.

The realization principle of ReflectionDynamicObject

ReflectionDynamicObject, which is derived from DynamicObject, gets all the properties and fields internally through reflection technology, stores its getter and setter methods and invokes them through the TryGetMember and TrySetMember methods at run time.

ReflectionDynamicObject source code public sealed class ReflectionDynamicObject: DynamicObject {private readonly object _ instance; private readonly Accessor _ accessor; private ReflectionDynamicObject (object instance) {_ instance = instance? Throw new ArgumentNullException (nameof (instance)); _ accessor = GetAccessor (instance.GetType ());} public static ReflectionDynamicObject Wrap (Object value) if (value = = null) throw new ArgumentNullException (nameof (value)); return new ReflectionDynamicObject (value); public override bool TryGetMember (GetMemberBinder binder, out object result) if (_ accessor.TryFindGetter (binder.Name, out var getter) {result = getter.Get (_ instance) Return true;} return base.TryGetMember (binder, out result); public override bool TrySetMember (SetMemberBinder binder, object value) if (_ accessor.TryFindSetter (binder.Name, out var setter)) setter.Set (_ instance, value); return base.TrySetMember (binder, value); # region Quick reflection private interface IGetter object Get (object instance) Private interface ISetter void Set (object instance, object value); private class Getter: IGetter private FieldInfo _ field; public Getter (FieldInfo field) _ field = field? Throw new ArgumentNullException (nameof (field)); public object Get (object instance) return _ field.GetValue (instance); private class Setter: ISetter public Setter (FieldInfo field) public void Set (object instance, object value) _ field.SetValue (instance, value); private class Getter: IGetter private readonly Func _ getter; public Getter (Func getter) _ getter = getter?? Throw new ArgumentNullException (nameof (getter)); return _ getter ((T1) instance); private class Setter: ISetter private readonly Action _ setter; public Setter (Action setter) this._setter = setter? Throw new ArgumentNullException (nameof (setter)); this._setter.Invoke ((T1) instance, (T2) value); private class Accessor public Accessor (Type type) this._type = type? Throw new ArgumentNullException (nameof (_ type)); var getter = new SortedDictionary (); var setter = new SortedDictionary (); var fields = _ type.GetFields (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (var field in fields) {getter [field.Name] = new Getter (field); setter [field.Name] = new Setter (field) } var props = _ type.GetProperties (BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (var item in props) if (item.CanRead) {var method = item.GetMethod; var funcType = typeof (Func) .MakeGenericType (item.DeclaringType, item.PropertyType) Var func = method.CreateDelegate (funcType); var getterType = typeof (Getter) .MakeGenericType (item.DeclaringType, item.PropertyType); var get = (IGetter) Activator.CreateInstance (getterType, func); getter [item.Name] = get } if (item.CanWrite) var method = item.SetMethod; var actType = typeof (Action) .MakeGenericType (item.DeclaringType, item.PropertyType); var act = method.CreateDelegate (actType); var setterType = typeof (Setter) .MakeGenericType (item.DeclaringType, item.PropertyType) Var set = (ISetter) Activator.CreateInstance (setterType, act); setter [item.Name] = set; _ getters = getter; _ setters = setter; private readonly Type _ type; private readonly IReadOnlyDictionary _ getters; private readonly IReadOnlyDictionary _ setters; public bool TryFindGetter (string name, out IGetter getter) = > _ getters.TryGetValue (name, out getter) Public bool TryFindSetter (string name, out ISetter setter) = > _ setters.TryGetValue (name, out setter); private static Dictionary _ accessors = new Dictionary (); private static object _ accessorsLock = new object (); private static Accessor GetAccessor (Type type) if (_ accessors.TryGetValue (type, out var accessor)) return accessor; lock (_ accessorsLock) if (_ accessors.TryGetValue (type, out accessor) return accessor; accessor = new Accessor (type) Var temp = new Dictionary (_ accessors); temp [type] = new Accessor (type); _ accessors = temp; return accessor; # endregion} ReflectionDynamicObject limitations

Based on complexity considerations, ReflectionDynamicObject does not add support for "methods". This means that the call to the method is missing. Although dynamic behavior frees the program from its dependence on strings, the implementation's support for "refactoring" is still unfriendly.

Where is ReflectionDynamicObject used?

Liquid theme engine is a set of HTML theme engine implemented by the author according to Liquid language and Shopify theme mechanism and using Fluid template engine. The engine allows end users to freely modify their theme templates without affecting the host. The ultimate goal is to be multilingual, multi-thematic, highly scalable, and WYSIWYG.

After reading this, the article "how to use ReflectionDynamicObject to optimize reflection on the .NET platform" has been introduced. If you want to master the knowledge of this article, you still need to practice and use it to understand it. If you want to know more about related articles, please follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report