模版标签主要分为两大类,栏目相关标签和文章相关标签,由于分属于两个表,对应不同的实体类,在替换模版标签的时候就出现了些问题.先把枋心类贴出来,好说明问题.
string patter = @"<!--(.+?):\{(.+?)\}-->([\s\S]*?)<!--\1-->";
MatchCollection maction = Regex.Matches(tempContext, patter, RegexOptions.Compiled);
foreach (Match mac in maction)
{
labName = mac.Groups[1].Value;
labAttr = mac.Groups[2].Value;
loopStr = mac.Groups[3].Value;
Aoner.BLL.Channel channel = new Aoner.BLL.Channel();
Aoner.BLL.Article articles = new Aoner.BLL.Article();
if (labName != "page")
{
tagRow = GetAttr(labAttr, "row", true) == null ? 5 : int.Parse(GetAttr(labAttr, "row", true));
tagMode = GetAttr(labAttr, "mode", true) == null ? "stat=0" : GetAttr(labAttr, "mode", true);
tagTable = GetAttr(labAttr, "table", true) == null ? "content" : GetAttr(labAttr, "table", true);
tagWhere = GetAttr(labAttr, "where", true) == null ? "" : GetAttr(labAttr, "where", true);
tagOrder = GetAttr(labAttr, "order", true) == null ? "id desc" : GetAttr(labAttr, "order", true);
StringBuilder strSql = new StringBuilder();
strSql.Append("select *");
strSql.Append(" from ");
strSql.Append(tagTable);
strSql.Append(" where " + tagMode);
if (tagWhere != "")
strSql.Append(" and " + tagWhere);
strSql.Append(" order by " + tagOrder);
strSql.Append(" Limit " + tagRow);
//HttpContext.Current.Response.Write(strSql.ToString()); //return;
string temp = tagTable == "channel" ? Loop<Aoner.Model.Channel>(@"\[" + labName + @":(.+?)\]", loopStr, channel.TempSql(strSql.ToString()), Attribute) : Loop<mArticle>(@"\[" + labName + @":(.+?)\]", loopStr, articles.TempSql(strSql.ToString()), Attribute);
//string temp = tagTable == "channel" ? loopChannel(channel.TempSql(strSql.ToString())) : loopArticle(articles.TempSql(strSql.ToString()));
tempContext = tempContext.Replace(mac.Value, temp);
}
}
string temp = tagTable == "channel" ?
在根据表名循环替换标签的时候,第一反应使用泛型方法:
Attribute方法两个版本:
(1)Attribute(string pattern,string loopStr,mArticle mart)
(2)Attribute(string pattern,string loopStr,mChannel mchannel)
private string Loop<T>(string patter,string loopStr,List<T> obj)
{
string temp = string.Empty;
foreach(T t in obj)
{
temp += Attribute(string patter,loopStr,t);
}
}
private string Loop<T>(string patter,string loopStr,List<T> obj)
{
string temp = string.Empty;
foreach(T t in obj)
{
temp += Attribute(string patter,loopStr,t);
}
}
还没等高兴过来,就发现编译报错,"T"类型不具有mArticle,mChannel两个类的属性,NND,泛型也不是万能;
接下来又尝试第二种方案:
把这两个方法分离到两个单独的类中,在根据条件来实例化,功能是实现了,可代码怎么看怎么便扭,两个类的代码百分之七八十是重复的,不爽,放弃.
这时想到了委托:
delegate string LoopReplace<T>(List<T> obj);
LoopReplace<mArticle> loopArticle = delegate(List<mArticle> marts)
{
string temps = string.Empty;
foreach (mArticle t in marts)
{
temps += Attribute(@"\[" + labName + @":(.+?)\]", loopStr, t);
}
return temps;
};
LoopReplace<Aoner.Model.Channel> loopChannel = delegate(List<Aoner.Model.Channel> marts)
{
string temps = string.Empty;
foreach (Aoner.Model.Channel t in marts)
{
temps += Attribute(@"\[" + labName + @":(.+?)\]", loopStr, t);
}
return temps;
};
比起第二方案来,大码大大减少,可还是感觉不爽,为啥就不能像泛型那样一个方法就足以应付各种情况呢?再次改良:
delegate string replace<T>(string pattern,string loop,T obj);
private string Loop<T>(string pattern,string loop,List<T> obj,replace<T> method)
{
string temps = string.Empty;
foreach (T t in obj)
{
temps += method(pattern, loop, t);
}
return temps;
}
string temp = tagTable == "channel" ? Loop<Aoner.Model.Channel>(@"\[" + labName + @":(.+?)\]", loopStr, channel.TempSql(strSql.ToString()), Attribute) : Loop<mArticle>(@"\[" + labName + @":(.+?)\]", loopStr, articles.TempSql(strSql.ToString()), Attribute);
这次总算是让自己满意了 :) 以前很少用委托,现在才发现它是这么可爱!!!
Tag标签: 模版解析,委托