zoukankan      html  css  js  c++  java
  • 动态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();
                    }
                }
            }
        }
  • 相关阅读:
    转载:KOF97东丈
    写一个ajax程序就是如此简单
    转载:97特瑞心得
    老生常谈:享元模式
    获得微软最有影响力开发者
    老生常谈设计模式系列文章索引
    asp.net中的异步页面
    转载:KOF97简易出招原理解析
    leaks 使用手册
    ObjectiveC中一种消息处理方法performSelector: withObject:
  • 原文地址:https://www.cnblogs.com/FlyCat/p/2659335.html
Copyright © 2011-2022 走看看