【问题标题】:how to execute string path on dynamic type?如何在动态类型上执行字符串路径?
【发布时间】:2011-01-27 03:51:17
【问题描述】:

是否可以在动态类型上执行字符串路径?

例如我们可以写动态类型

dynamic d = myObj;
var v = d.MyMethod(1,"text").SomeProperty.Name

现在想象我有字符串路径

string path = "MyMethod(1,\"text\").SomeProperty.Name";
var v = d. //How to applay string path to this type?

【问题讨论】:

    标签: c# dynamic .net-4.0


    【解决方案1】:

    我有使用扩展方法和反射的解决方案,您需要针对不同的场景进行优化和测试。

    编辑 仍然是脏代码,但现在支持重载方法。我将尝试进行代码清理并使用正则表达式来获得有效和更清洁的解决方案

    您现在可以为 eval 方法指定参数的数据类型。

    string epath = "GetName(System_String: ding dong, System_Int32:1).name";
    MyClass cls = new MyClass();
    var v = cls.Eval(epath);
    

    注意类型名称中的下划线。如果方法没有重载,这应该可以在不提及数据类型的情况下工作。当前限制,您不能在字符串参数值中使用冒号或逗号。 :(

    打电话给var v = d.Execute(path)

            public static object Eval(this object instance, string path)
        {
            string[] cmd = path.Split('.');
            string subString = cmd[0];
            object returnValue = null;
            Type t = instance.GetType();
            if (subString.Contains("("))
            {
                string[] paramString = subString.Split('(');
                string[] parameters = paramString[1].Replace(")", "").Split(new Char[]{','},StringSplitOptions.RemoveEmptyEntries);
                bool hasNoParams = parameters.Length == 0;
    
                List<Type> typeArray = null;
                if (hasNoParams) typeArray = new List<Type>();
                foreach (string parameter in parameters)
                {
                    if (parameter.Contains(":"))
                    {
                        if (typeArray == null) typeArray = new List<Type>();
                        string[] typeValue = parameter.Split(':');
                        Type paramType = Type.GetType(typeValue[0].Replace('_','.'));
    
                        typeArray.Add(paramType);
                    }
                }
                MethodInfo info = null;
                if (typeArray == null)
                    info = t.GetMethod(paramString[0]);
                else
                    info = t.GetMethod(paramString[0], typeArray.ToArray());
                ParameterInfo[] pInfo = info.GetParameters();
                List<object> paramList = new List<object>();
                for (int i = 0; i < pInfo.Length; i++)
                {
                    string currentParam = parameters[i];
                    if (currentParam.Contains(":"))
                    {
                        currentParam = currentParam.Split(':')[1];
                    }
                    ParameterInfo pram = pInfo[i];
                    Type pType = pram.ParameterType;
                    object obj = Convert.ChangeType(currentParam, pType);
                    paramList.Add(obj);
                }
                if (info == null) returnValue = null;
                else
                    returnValue = info.Invoke(instance, paramList.ToArray());
            }
            else
            {
    
                PropertyInfo pi = t.GetProperty(subString);
                if (pi == null) returnValue = null;
                else
                    returnValue = pi.GetValue(instance, null);
            }
            if (returnValue == null || cmd.Length == 1)
                return returnValue;
            else
            {
                returnValue = returnValue.Eval(path.Replace(cmd[0] + ".", ""));
            }
            return returnValue;
        }
    

    【讨论】:

    • 非常感谢@hungryMind,我会试试的
    【解决方案2】:

    不确定这是否可以轻松实现。我过去一直在使用Spring.NET Expressions

    【讨论】:

      【解决方案3】:

      您似乎需要一个 eval 函数,而 C# 没有,但如果 this third party C# eval implementation 可以处理 dynamic 它可能会解决您的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-09-24
        • 2017-04-15
        • 2011-05-09
        • 1970-01-01
        • 2016-03-31
        • 1970-01-01
        • 1970-01-01
        • 2021-12-12
        相关资源
        最近更新 更多