| | | 1 | | // Licensed to the .NET Foundation under one or more agreements. |
| | | 2 | | // The .NET Foundation licenses this file to you under the MIT license. |
| | | 3 | | |
| | | 4 | | using System; |
| | | 5 | | using System.Linq.Expressions; |
| | | 6 | | using System.Reflection; |
| | | 7 | | |
| | | 8 | | namespace CoreWCF.Runtime.Serialization |
| | | 9 | | { |
| | | 10 | | internal static class ReflectionHelper |
| | | 11 | | { |
| | | 12 | | internal static Func<object, TProp> GetPropertyDelegate<TProp>(Type declaringType, string propertyName) |
| | | 13 | | { |
| | | 14 | | Fx.Assert(declaringType != null, "declaringType can't be null"); |
| | 28 | 15 | | var propertyInfo = declaringType.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | Bin |
| | | 16 | | Fx.Assert(propertyInfo != null, $"Type {declaringType.Name} doesn't have a property called {propertyName}"); |
| | 28 | 17 | | var propertyGetter = propertyInfo.GetGetMethod(nonPublic: true); |
| | 28 | 18 | | return CreateInstanceMethodCallLambda<TProp>(propertyGetter, declaringType); |
| | | 19 | | } |
| | | 20 | | |
| | | 21 | | internal static Func<TInstance, TProp> GetPropertyDelegate<TInstance, TProp>(string propertyName) |
| | | 22 | | { |
| | 2 | 23 | | var propertyInfo = typeof(TInstance).GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | |
| | | 24 | | Fx.Assert(propertyInfo != null, $"Type {typeof(TInstance).Name} doesn't have a property called {propertyName |
| | 2 | 25 | | var propertyGetter = propertyInfo.GetGetMethod(nonPublic: true); |
| | 2 | 26 | | return CreateInstanceMethodCallLambda<TInstance, TProp>(propertyGetter); |
| | | 27 | | } |
| | | 28 | | |
| | | 29 | | internal static Action<object, TProp> SetPropertyDelegate<TProp>(Type declaringType, string propertyName) |
| | | 30 | | { |
| | | 31 | | Fx.Assert(declaringType != null, "declaringType can't be null"); |
| | 0 | 32 | | var propertyInfo = declaringType.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public | Bin |
| | | 33 | | Fx.Assert(propertyInfo != null, $"Type {declaringType.Name} doesn't have a property called {propertyName}"); |
| | 0 | 34 | | var propertySetter = propertyInfo.GetSetMethod(nonPublic: true); |
| | 0 | 35 | | return CreateVoidInstanceMethodCallWithParamLambda<TProp>(propertySetter, declaringType); |
| | | 36 | | } |
| | | 37 | | |
| | | 38 | | internal static Func<TParam, TReturn> CreateStaticMethodCallLambda<TParam, TReturn>(MethodInfo methodInfo) |
| | | 39 | | { |
| | 0 | 40 | | var paramExpression = Expression.Parameter(typeof(TParam), "param"); |
| | 0 | 41 | | Expression callExpr = Expression.Call(methodInfo, paramExpression); |
| | 0 | 42 | | if (typeof(TReturn) != typeof(object)) |
| | | 43 | | { |
| | 0 | 44 | | callExpr = Expression.Convert(callExpr, typeof(TReturn)); |
| | | 45 | | } |
| | | 46 | | |
| | 0 | 47 | | var lambdaExpr = Expression.Lambda<Func<TParam, TReturn>>(callExpr, paramExpression); |
| | 0 | 48 | | return lambdaExpr.Compile(); |
| | | 49 | | } |
| | | 50 | | |
| | | 51 | | internal static Func<object, TReturn> CreateInstanceMethodCallLambda<TReturn>(MethodInfo methodInfo, Type instan |
| | | 52 | | { |
| | 28 | 53 | | var instanceObjParamExpr = Expression.Parameter(typeof(object), "instance"); |
| | 28 | 54 | | var typeInstanceExpr = Expression.Convert(instanceObjParamExpr, instanceType); |
| | 28 | 55 | | Expression callExpr = Expression.Call(typeInstanceExpr, methodInfo); // No parameters for this method |
| | 28 | 56 | | if (typeof(TReturn) != typeof(object)) |
| | | 57 | | { |
| | 20 | 58 | | callExpr = Expression.Convert(callExpr, typeof(TReturn)); |
| | | 59 | | } |
| | | 60 | | |
| | 28 | 61 | | var lambdaExpr = Expression.Lambda<Func<object, TReturn>>(callExpr, instanceObjParamExpr); |
| | 28 | 62 | | return lambdaExpr.Compile(); |
| | | 63 | | } |
| | | 64 | | |
| | | 65 | | internal static Func<TInstance, TReturn> CreateInstanceMethodCallLambda<TInstance, TReturn>(MethodInfo methodInf |
| | | 66 | | { |
| | 2 | 67 | | var instanceParamExpr = Expression.Parameter(typeof(TInstance), "instance"); |
| | 2 | 68 | | Expression callExpr = Expression.Call(instanceParamExpr, methodInfo); // No parameters for this method |
| | 2 | 69 | | if (typeof(TReturn) != typeof(object)) |
| | | 70 | | { |
| | 0 | 71 | | callExpr = Expression.Convert(callExpr, typeof(TReturn)); |
| | | 72 | | } |
| | | 73 | | |
| | 2 | 74 | | var lambdaExpr = Expression.Lambda<Func<TInstance, TReturn>>(callExpr, instanceParamExpr); |
| | 2 | 75 | | return lambdaExpr.Compile(); |
| | | 76 | | } |
| | | 77 | | |
| | | 78 | | internal static Action<object, TParam> CreateVoidInstanceMethodCallWithParamLambda<TParam>(MethodInfo methodInfo |
| | | 79 | | { |
| | 0 | 80 | | var instanceObjParamExpr = Expression.Parameter(typeof(object), "instance"); |
| | 0 | 81 | | var typeInstanceExpr = Expression.Convert(instanceObjParamExpr, instanceType); |
| | 0 | 82 | | var firstParamParamExpr = Expression.Parameter(typeof(TParam), "param"); |
| | 0 | 83 | | Expression callExpr = Expression.Call(typeInstanceExpr, methodInfo, firstParamParamExpr); |
| | 0 | 84 | | var lambdaExpr = Expression.Lambda<Action<object, TParam>>(callExpr, instanceObjParamExpr, firstParamParamEx |
| | 0 | 85 | | return lambdaExpr.Compile(); |
| | | 86 | | } |
| | | 87 | | } |
| | | 88 | | } |