本篇體驗擴展StringBuilder使之支持鏈式方法。
這裡有一個根據鍵值集合生成select元素的方法。
private static string BuilderSelectBox(IDictionary<int, string> options, string id, bool includeUnknown)
{
var html = new StringBuilder();
html.AppendFormat("<select id=\"{0}\" name=\"{0}\">", id);
html.AppendLine();
if(includeUnknown)
{
html.AppendLine("\t<option>Unknown</option>");
}
foreach(var opt in options)
{
html.AppendFormat("\t<option value=\"{0}\">{1}</option>", opt.Key, opt.Value);
html.AppendLine();
}
html.AppendLine("</select>");
return html.ToString();
}
以上,
html.AppendFormat("<select id=\"{0}\" name=\"{0}\">", id);
html.AppendLine();
可以對這兩個語句封裝,擴展StringBuilder。
改成
public static class StringBuilderExtensions
{
public static StringBuilder AppendFormattedLine(this StringBuilder @this, string format, prams object[] args) => @this.AppendFormat(format, args).AppendLine();
}
private static string BuilderSelectBox(IDictionary<int, string> options, string id, bool includeUnknown)
{
var html = new StringBuilder()
.AppendFormattedLine("<select id=\"{0}\" name=\"{0}\">", id);
if(includeUnknown)
{
html.AppendLine("\t<option>Unknown</option>");
}
foreach(var opt in options)
{
html.AppendFormattedLine("\t<option value=\"{0}\">{1}</option>", opt.Key, opt.Value);
html.AppendLine();
}
html.AppendLine("</select>");
return html.ToString();
}
以上,
if(includeUnknown)
{
html.AppendLine("\t<option>Unknown</option>");
}
可以對如上語句進行封裝,繼續擴展StringBuilder.
public static class StringBuilderExtensions
{
public static StringBuilder AppendFormattedLine(this StringBuilder @this, string format, prams object[] args) => @this.AppendFormat(format, args).AppendLine();
public static StringBuilder AppendLineWhen(this StringBuilder @this, Func<bool> predicate, string value) =>
predicate()
? @this.AppendLine(value)
: @this;
}
private static string BuilderSelectBox(IDictionary<int, string> options, string id, bool includeUnknown)
{
var html = new StringBuilder()
.AppendFormattedLine("<select id=\"{0}\" name=\"{0}\">", id)
.AppendLineWhen(() => includeUnknown, "\t<option>Unknown</option>");
foreach(var opt in options)
{
html.AppendFormattedLine("\t<option value=\"{0}\">{1}</option>", opt.Key, opt.Value);
}
html.AppendLine("</select>");
return html.ToString();
}
或
public static class StringBuilderExtensions
{
public static StringBuilder AppendFormattedLine(this StringBuilder @this, string format, prams object[] args) => @this.AppendFormat(format, args).AppendLine();
public static StringBuilder AppendLineWhen(this StringBuilder @this, Func<bool> predicate, string value) =>
predicate()
? @this.AppendLine(value)
: @this;
public static StringBuilder AppendWhen(this StringBuilder @this, Func<bool> predicate, Func<StringBuilder, StringBuilder> fn) =>
predicate()
? fn(@this)
: @this;
}
private static string BuilderSelectBox(IDictionary<int, string> options, string id, bool includeUnknown)
{
var html = new StringBuilder()
.AppendFormattedLine("<select id=\"{0}\" name=\"{0}\">", id)
.AppendWhen(
() => includeUnknown,
sb => sb.AppendLine("\t<option>Unknown</option>")
);
foreach(var opt in options)
{
html.AppendFormattedLine("\t<option value=\"{0}\">{1}</option>", opt.Key, opt.Value);
}
html.AppendLine("</select>");
return html.ToString();
}
以上,
foreach(var opt in options)
{
html.AppendFormattedLine("\t<option value=\"{0}\">{1}</option>", opt.Key, opt.Value);
}
對遍歷語句進行封裝,擴展StringBuilder,最終:
public static class StringBuilderExtensions
{
public static StringBuilder AppendFormattedLine(this StringBuilder @this, string format, prams object[] args) => @this.AppendFormat(format, args).AppendLine();
public static StringBuilder AppendLineWhen(this StringBuilder @this, Func<bool> predicate, string value) =>
predicate()
? @this.AppendLine(value)
: @this;
public static StringBuilder AppendWhen(this StringBuilder @this, Func<bool> predicate, Func<StringBuilder, StringBuilder> fn) =>
predicate()
? fn(@this)
: @this;
public static StringBuilder AppendSequence<T>(this StringBuilder @this, IEnumerable<T> seq, Func<StringBuilder, T, StringBuilder> fn) => seq.Aggregate(@this, fn);
}
private static string BuilderSelectBox(IDictionary<int, string> options, string id, bool includeUnknown)
{
var html = new StringBuilder()
.AppendFormattedLine("<select id=\"{0}\" name=\"{0}\">", id)
.AppendWhen(
() => includeUnknown,
sb => sb.AppendLine("\t<option>Unknown</option>")
)
.AppendSequence(options, (sb, opt) => sb.AppendFormattedLine("\t<option value=\"{0}\">{1}</option>", opt.Key, opt.Value))
.AppendLine("</select>")
.ToString();
}