How to refactor these functions which have one line difference
I have 3 functions where the only difference in is the values I point out with comment
//-- point of difference
The majority of the function is the same across all three. The "DRY" factor is haunting my sleep :). I was wondering; can these could be merged easily and readably?
I have had situations like this before and I am hoping to learn something here.
private string RenderRequestType(string render, NameValueCollection nvp, string prefix, string regexWild, string suffix)
{
string regex = prefix + regexWild + suffix;
MatchCollection matches = Regex.Matches(render, regex);
foreach (Match match in matches)
{
foreach (Capture capture in match.Captures)
{
string name = capture.Value.Replace(prefix, "", StringComparison.CurrentCultureIgnoreCase).Replace(suffix, "", StringComparison.CurrentCultureIgnoreCase);
//-- point of difference
string value = nvp[name];
render = render.Replace(capture.Value, value);
}
}
return render;
}
private string RenderSessionType(string render, HttpContext httpContext, string prefix, string regexWild, string suffix)
{
string regex = prefix + regexWild + suffix;
MatchCollection matches = Regex.Matches(render, regex);
foreach (Match match in matches)
{
foreach (Capture capture in match.Captures)
{
string name = capture.Value.Replace(prefix, "", StringComparison.CurrentCultureIgnoreCase).Replace(suffix, "", StringComparison.CurrentCultureIgnoreCase);
//-- point of difference
object session = httpContext.Session[name];
string value = (session != null ? session.ToString() : "");
render = render.Replace(capture.Value, value);
}
}
return render;
}
private string RenderCook开发者_Python百科ieType(string render, HttpContext httpContext, string prefix, string regexWild, string suffix)
{
string regex = prefix + regexWild + suffix;
MatchCollection matches = Regex.Matches(render, regex);
foreach (Match match in matches)
{
foreach (Capture capture in match.Captures)
{
string name = capture.Value.Replace(prefix, "", StringComparison.CurrentCultureIgnoreCase).Replace(suffix, "", StringComparison.CurrentCultureIgnoreCase);
//-- point of difference
HttpCookie cookie = httpContext.Request.Cookies[name];
string value = (cookie != null ? cookie.Value : "");
render = render.Replace(capture.Value, value);
}
}
return render;
}
You could modify the function to take a Func<string, string>
to do the lookup:
private string RenderType(string render, Func<string, string> lookupFunc, string prefix, string regexWild, string suffix)
{
string regex = prefix + regexWild + suffix;
MatchCollection matches = Regex.Matches(render, regex);
foreach (Match match in matches)
{
foreach (Capture capture in match.Captures)
{
string name = capture.Value.Replace(prefix, "", StringComparison.CurrentCultureIgnoreCase).Replace(suffix, "", StringComparison.CurrentCultureIgnoreCase);
//-- point of difference
string value = lookupFunc(name);
render = render.Replace(capture.Value, value);
}
}
return render;
}
Then write your functions in terms of this one, e.g.:
private string RenderRequestType(string render, NameValueCollection nvp, string prefix, string regexWild, string suffix)
{
return RenderType(render, name => nvp[name], prefix, regexWild, suffix);
}
Pass in a Func<string, string>
to get the value associated with a given name. In the first case that would just use nvp's indexer; in the second it would use the session. You could either use separate methods to create the delegates, or lambda expressions. (I'd definitely use a lambda expression for the first one; I might use a separate method for the second.)
In my opinion the best solution is to use lambda expressions.
Instead of second argument to your functions, put there lambda which will transform string name
to string value
.
精彩评论