[. NET] Quick notes on Objective C,
Quick notes in Objective C #-Dynamic Programming in C #
This series
Quick notes in Objective C # (1)-C # language habits
Quick notes for Objective C # (2)-. NET resource hosting
Quick notes in Objective C # (III)-use C # To express design
Quick notes for Objective C # (4)-use the framework
Quick notes in Objective C #-Dynamic Programming in C #
I. Directory
- 38. Understand the advantages and disadvantages of dynamic types
- 39. Use Dynamic types to express the runtime type of generic parameters
- 40. Declare parameters that accept the anonymous type as dynamic
- Forty-one. Use DynamicObject or IDynamicMetaObjectProvider to implement dynamic data-driven data types.
- . How to Use expression API
- Forty-three, use expressions to convert delayed binding to pre-binding
- Forty-four, minimize the use of dynamic types in public APIs
38. Understand the advantages and disadvantages of dynamic types
Here, I use three numeric Addition Methods: dynamic dynamics, Func delegation, and Expression Tree addition:
[TestMethod] public void Test () {var result1 = AddDynamic (2, 3); Console. writeLine (int) result1); var result2 = AddFunc (3, 4, (x, y) => x + y); Console. writeLine (result2); var result3 = AddExpressionTree (4, 5); Console. writeLine (result3);} // <summary> // Add, dynamic /// </summary> /// <param name = "a"> </param> /// <param name = "B"> </param> // /<returns> </returns> private dynamic AddDynamic (dynamic, dynamic B) {return a + B;} // <summary> // Add, use delegate /// </summary> /// <typeparam name = "T1"> </typeparam> /// <typeparam name = "T2"> </typeparam>/ // <typeparam name = "TR"> </typeparam> // <param name = "a"> </param> // <param name = "B"> </param> /// <param name = "func"> </param> /// <returns> </returns> private TR AddFunc <T1, t2, TR> (T1 a, T2 B, Func <T1, T2, TR> func) {return func (a, B );} /// <summary> /// Add, use Expression Tree /// </summary> /// <typeparam name = "T"> </typeparam> /// <param name = "a"> </param> /// <param name = "B"> </param> // <returns> </returns> private T AddExpressionTree <T> (T, T B) {ParameterExpression leftOperand = Expression. parameter (typeof (T), "left"); ParameterExpression rightOperand = Expression. parameter (typeof (T), "right"); BinaryExpression body = Expression. add (leftOperand, rightOperand); Expression <Func <T, T, T> adder = Expression. lambda <Func <T, T, T> (body, leftOperand, rightOperand); Func <T, T, T> theDelegate = adder. compile (); return theDelegate (a, B );}}
39. Use Dynamic types to express the runtime type of generic parameters
40. Declare parameters that accept the anonymous type as dynamic
Forty-one. Use DynamicObject or IDynamicMetaObjectProvider to implement dynamic data-driven data types.
This is an example of implementing a dynamic type model. In addition to inheriting DynamicObject, you also need to override TryGetMemebr () and TrySetMemebr ().
[TestMethod] public void Test1 () {dynamic propDynamic = new DynamicPropertyBag (); propDynamic. now = DateTime. now; Console. writeLine (propDynamic. now) ;}/// <summary> /// dynamic attribute binding model /// </summary> internal class DynamicPropertyBag: DynamicObject {private readonly Dictionary <string, object >_storage = new Dictionary <string, object> (); /// <summary> /// obtain the property value /// </summary> /// <param name = "binder"> </param> /// <param name = "result"> </param> // <returns> </returns> public override bool TryGetMember (GetMemberBinder binder, out object result) {var key = binder. name; if (_ storage. containsKey (key) {result = _ storage [key]; return true;} result = null; return false ;} /// <summary> /// set the property value /// </summary> /// <param name = "binder"> </param> /// <param name = "value"> </param> // <returns> </returns> public override bool TrySetMember (SetMemberBinder binder, object value) {var key = binder. name; try {if (_ storage. containsKey (key) {_ storage [key] = value;} else {_ storage. add (key, value) ;}return true;} catch (Exception e) {Console. writeLine (e); return false ;}}
[TestMethod] public void Test2 () {var result = Call <int, string> (x) => (x * 2 ). toString ("D"); Console. writeLine (result );} /// <summary> /// call /// </summary> /// <typeparam name = "T"> </typeparam> /// <typeparam name =" TResult "> </typeparam> // <param name =" op "> </param> // <returns> </returns> private TResult Call <T, TResult> (Expression <Func <T, TResult> op) {var exp = op. body as MethodCallExpression; var result = default (TResult); if (exp = null) {return result;} var methodName = exp. method. name; var parameters = exp. arguments. select (ProcessArgument); Console. writeLine ($ "method name {methodName}"); foreach (var parameter in parameters) {Console. writeLine ("parameter:"); Console. writeLine ($ "\ t {parameter. item1 }:{ parameter. item2} ");} return result ;} /// <summary> /// processing parameter /// </summary> /// <param name = "expression"> </param> /// <returns> </returns> private Tuple <Type, object> ProcessArgument (Expression expression) {object arg = default (object); LambdaExpression l = Expression. lambda (Expression. convert (expression, expression. type); Type parmType = l. returnType; arg = l. compile (). dynamicInvoke (); return Tuple. create (parmType, arg );}
[Reference] Objective C #
Http://blog.csdn.net/w174504744/article/details/50562109 (reference)