• 动态string转换类


    主要用于反射运行时转换类型

      class ConvertString
        {
            private static Dictionary<Type, DynamicMethodExecutor> executorCache = new Dictionary<Type, DynamicMethodExecutor>();
            /// <summary>
            /// Type必须有静态Parse方法供转换调用
            /// </summary>
            /// <param name="value"></param>
            /// <param name="type"></param>
            /// <returns></returns>
            public static object ToType(string value, Type type)
            {
                if (type == typeof(string)) { return value; }
                DynamicMethodExecutor executor = null;
                if (executorCache.TryGetValue(type, out executor) == false)
                {
                    MethodInfo parseMethod = null;
                    foreach (MethodInfo mi in type.GetMethods(BindingFlags.Static | BindingFlags.Public))
                    {
                        if (mi.Name == "Parse" && mi.GetParameters().Length == 1 && mi.GetParameters()[0].ParameterType == typeof(string))
                        {
                            parseMethod = mi; break;
                        }
                    }
                    if (parseMethod == null)
                    {
                        throw new ArgumentException(string.Format("Type: {0} has not Parse static method!", type));
                    }
                    executor = new DynamicMethodExecutor(parseMethod);
                    executorCache[type] = executor;
                }
                return executor.Execute(null, new object[] { value });
            }
    
    
            private class DynamicMethodExecutor
            {
                private Func<object, object[], object> m_execute;
    
                public DynamicMethodExecutor(MethodInfo methodInfo)
                {
                    this.m_execute = this.GetExecuteDelegate(methodInfo);
                }
    
                public object Execute(object instance, object[] parameters)
                {
                    return this.m_execute(instance, parameters);
                }
    
                private Func<object, object[], object> GetExecuteDelegate(MethodInfo methodInfo)
                {
                    // parameters to execute
                    ParameterExpression instanceParameter =
                        Expression.Parameter(typeof(object), "instance");
                    ParameterExpression parametersParameter =
                        Expression.Parameter(typeof(object[]), "parameters");
    
                    // build parameter list
                    List<Expression> parameterExpressions = new List<Expression>();
                    ParameterInfo[] paramInfos = methodInfo.GetParameters();
                    for (int i = 0; i < paramInfos.Length; i++)
                    {
                        // (Ti)parameters[i]
                        BinaryExpression valueObj = Expression.ArrayIndex(
                            parametersParameter, Expression.Constant(i));
                        UnaryExpression valueCast = Expression.Convert(
                            valueObj, paramInfos[i].ParameterType);
    
                        parameterExpressions.Add(valueCast);
                    }
    
                    // non-instance for static method, or ((TInstance)instance)
                    Expression instanceCast = methodInfo.IsStatic ? null :
                        Expression.Convert(instanceParameter, methodInfo.ReflectedType);
    
    
                    // static invoke or ((TInstance)instance).Method
                    MethodCallExpression methodCall = Expression.Call(
                        instanceCast, methodInfo, parameterExpressions);
    
                    // ((TInstance)instance).Method((T0)parameters[0], (T1)parameters[1], ...)
                    if (methodCall.Type == typeof(void))
                    {
                        Expression<Action<object, object[]>> lambda =
                            Expression.Lambda<Action<object, object[]>>(
                                methodCall, instanceParameter, parametersParameter);
    
                        Action<object, object[]> execute = lambda.Compile();
                        return (instance, parameters) =>
                        {
                            execute(instance, parameters);
                            return null;
                        };
                    }
                    else
                    {
                        UnaryExpression castMethodCall = Expression.Convert(
                            methodCall, typeof(object));
                        Expression<Func<object, object[], object>> lambda =
                            Expression.Lambda<Func<object, object[], object>>(
                                castMethodCall, instanceParameter, parametersParameter);
    
                        return lambda.Compile();
                    }
                }
            }
        }
  • 相关阅读:
    Python处理海量手机号码
    javascript面向对象
    NET实现的DDD、CQRS与微服务架构
    增加打赏功能
    开发测试时给 Kafka 发消息的 UI 发送器――Mikasa
    Computational Network Toolkit (CNTK) 是微软出品的开源深度学习工具包
    线程同步和多线程优先级
    linux sed命令详解(转)
    linux sort,uniq,cut,wc命令详解 (转)
    linux awk命令详解(转)
  • 原文地址:https://www.cnblogs.com/FlyCat/p/2659335.html
Copyright © 2020-2023  润新知