2011-01-26 64 views
4

是否可以在動態類型上執行字符串路徑?如何在動態類型上執行字符串路徑?

例如,具有動態類型,我們可以寫

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? 

回答

2

我有使用擴展方法和反射的解決方案,您需要針對不同的場景進行優化和測試。

編輯 仍然髒代碼,但現在支持重載的方法。我將嘗試執行代碼清理並使用正則表達式來實現更有效和更清潔的解決方案

您可以爲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; 
    } 
+0

非常感謝@hungryMind,我會嘗試 – 2011-01-26 12:20:09