如何执行动态类型的字符串路径?字符串、路径、类型、动态

2023-09-07 15:54:27 作者:抹不掉丶残留记忆

是否有可能执行动态类型的字符串路径?

例如具有动态类型,我们可以写

 动态D = MyObj中;
变种ν= d.MyMethod(1,文)。SomeProperty.Name
 

现在想象我有字符串路径

 字符串路径=的MyMethod(1,\文\)。SomeProperty.Name;
变种V =Ð。 //如何applay字符串的路径这种类型的?
 
一图掌握如何进行活动策划

解决方案

我在使用扩展​​方法和反思,需要优化和测试针对不同场景的解决方案。

修改 还是很脏code,但现在支持重载方法。我会尽量做到code清理,并使用正则表达式进行有效和更清洁的解决方案

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

 字符串EPATH =的GetName(System_String:叮咚,System_Int32:1)。名称;
MyClass的CLS =新MyClass的();
变种V = cls.Eval(EPATH);
 

请注意下划线的类型名称。这应该不提的数据类型,如果方法不超载。当前的限制,你不能用冒号或逗号在字符串参数值。 :(

呼叫像变种V = d.Execute(路径)

 公共静态对象的eval(此对象实例,字符串路径)
    {
        字符串[] CMD = path.Split('。');
        字符串的子串= CMD [0];
        对象的returnValue = NULL;
        类型t = instance.GetType();
        如果(subString.Contains(())
        {
            字符串[]中的paramString = subString.Split('(');
            串[]参数=的paramString [1] .Replace(),).Split(新字符[] {','},StringSplitOptions.RemoveEmptyEntries);
            布尔hasNoParams = parameters.Length == 0;

            名单<类型> typeArray = NULL;
            如果(hasNoParams)typeArray =新名单,其中,类型和GT;();
            的foreach(在参数字符串参数)
            {
                如果(parameter.Contains(:))
                {
                    如果(typeArray == NULL)typeArray =新名单,其中,类型和GT;();
                    字符串[] typeValue = parameter.Split(:);
                    键入paramType = Type.GetType(typeValue [0] .Replace('_',)'。');

                    typeArray.Add(paramType);
                }
            }
            MethodInfo的信息= NULL;
            如果(typeArray == NULL)
                信息= t.GetMethod(中的paramString [0]);
            其他
                信息= t.GetMethod(中的paramString [0],typeArray.ToArray());
            信息参数[] PINFO = info.GetParameters();
            名单<对象> paramList =新的名单,其中,对象>();
            的for(int i = 0; I< pInfo.Length;我++)
            {
                字符串currentParam =参数[I]
                如果(currentParam.Contains(:))
                {
                    currentParam = currentParam.Split(:)[1];
                }
                信息参数PRAM = PINFO [I]
                键入P型= pram.ParameterType;
                obj对象= Convert.ChangeType(currentParam,P型);
                paramList.Add(OBJ);
            }
            如果(资讯== NULL)的returnValue = NULL;
            其他
                的returnValue = info.Invoke(例如,paramList.ToArray());
        }
        其他
        {

            的PropertyInfo PI = t.GetProperty(串);
            如果(PI == NULL)的returnValue = NULL;
            其他
                的returnValue = pi.GetValue(例如,NULL);
        }
        如果(的returnValue == NULL || cmd.Length == 1)
            返回的returnValue;
        其他
        {
            的returnValue = returnValue.Eval(path.Replace(CMD [0] +,)。);
        }
        返回的returnValue;
    }
 

Is it possible to execute string path on dynamic type?

For example having dynamic type we can write

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

Now imagine I have string path

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

解决方案

I have solution using extension method and reflection, you need to optimize and test for different scenario.

EDIT Still dirty code, but supports overloaded method now. I will try to do code clean up and use regex for effective and cleaner solution

You can specify data types for parameters now to the eval method.

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

Note underscore in type names. This should work without mentioning datatypes if method are not overloaded. Current restriction, you cannot use colon or comma inside string parameter value. :(

Call like 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;
    }