是否可以在動態類型上執行字符串路徑?如何在動態類型上執行字符串路徑?
例如,具有動態類型,我們可以寫
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?
是否可以在動態類型上執行字符串路徑?如何在動態類型上執行字符串路徑?
例如,具有動態類型,我們可以寫
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?
我有使用擴展方法和反射的解決方案,您需要針對不同的場景進行優化和測試。
編輯 仍然髒代碼,但現在支持重載的方法。我將嘗試執行代碼清理並使用正則表達式來實現更有效和更清潔的解決方案
您可以爲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;
}
不知道這是否可以很容易地實現。我過去一直在使用Spring.NET Expressions。
看來你需要一個評估函數和C#沒有,但如果this third party C# eval implementation可以處理dynamic
它可能會解決您的問題。
非常感謝@hungryMind,我會嘗試 – 2011-01-26 12:20:09