動態代碼中以 `$` 開頭標識外部變量(如 `$argname`),執行前需替換為可存取 Context 字典的包裝物件:
// 處理未初始化的環境變量
Regex re = new Regex(@"^(\$)(\w)+");
if (inputCmdString != null)
{
Match m = re.Match(inputCmdString);
if (m != null && m.Length > 1)
{
String outArgName = inputCmdString.Substring(m.Index, m.Length).Substring(1);
if (this[outArgName] == null)
{
String innerArgName = "TempArg_" + outArgName;
inputCmdString = "var " + inputCmdString.Replace("$" + outArgName, innerArgName);
inputCmdString += ";m_context[\"" + outArgName + "\"]=" + innerArgName + ";";
}
}
}
// 處理其它環境變量
re = new Regex(@"(\$)(\w)+");
IDictionary ArgsList = new Dictionary();
if (inputCmdString != null)
{
MatchCollection mc = re.Matches(inputCmdString);
if (mc != null)
{
foreach (Match m in mc)
{
if (m.Length > 1)
{
String outArgName = inputCmdString.Substring(m.Index, m.Length).Substring(1);
if (!ArgsList.ContainsKey(outArgName))
{
Object obj = this[outArgName];
if (obj == null) throw new Exception("不存在環境變量 " + outArgName);
// 關鍵:使用 ObjectHelper 包裝實現雙向繫結
String innerArgName = String.Format(
@"(new ObjectHelper<{0}>(m_context,""{1}"")).Obj",
obj.GetType(), outArgName);
ArgsList.Add(outArgName, innerArgName);
}
}
}
}
}
// 批次替換
foreach (String outArg in ArgsList.Keys)
{
inputCmdString = inputCmdString.Replace("$" + outArg, ArgsList[outArg]);
}
解決直接 Cast 無法賦值的問題,實現 Context 字典值的強型別存取與寫回:
public class ObjectHelper
{
private String m_objName;
public Context Context { get; private set; }
public T Obj
{
get
{
Object obj = Context[m_objName];
return (T)obj;
}
set { Context[m_objName] = value; }
}
public ObjectHelper(Context cxt, String objName)
{
m_objName = objName;
Context = cxt;
}
}