典型的なコード(やや不自然な例ですが、それでも):
void SomeFunc(string arg1, string arg2, string arg3) { string msg = ""; if (arg1 == null) msg += "ARG1 "; if (arg2 == null) msg += "ARG2 "; if (arg3 == null) msg += "ARG3 "; if (msg != "") throw new ArgumentNullException(msg); //... }
出力で、すべての引数がゼロの場合、文字列"ARG1 ARG2 ARG3"を取得します。
そして、 「ARG1 、 ARG2 、 ARG3」が必要な場合は? それとも「ARG1 、 ARG2 、 ARG3」ですか?
この場合、非常に頻繁に(最後の単語の前に特別な区切り文字を使用しない場合)、次の解決策を使用します。
void SomeFunc(string arg1, string arg2, string arg3) { string msg = ""; if (arg1 == null) msg += "ARG1, "; if (arg2 == null) msg += "ARG2, "; if (arg3 == null) msg += "ARG3, "; if (msg.EndsWith(", ")) msg = msg.Substring(0, msg.Length - 2); if (msg != "") throw new ArgumentNullException(msg); //... }
言い換えると、各単語の後にセパレーターを配置し、行の最後に余分なセパレーターを「バイト」します。
「余分な」引数が行の先頭に追加され、現在次のフラグメントの前にセパレータが書き込まれている場合、同じメソッドのわずかなバリエーションがまだあります。 加えて、行末から何も切り捨てる必要はありません。 以下は、このアプローチが使用される1つの例です。
string BuildSQL(string arg1, string arg2, string arg3) { string sql = "SELECT * FROM table_1 WHERE 1=1 "; if (arg1 != null) sql += "AND ARG1 = ? "; if (arg2 != null) sql += "AND ARG1 = ? "; if (arg3 != null) sql += "AND ARG1 = ? "; return sql; }
さまざまな条件の組み合わせが整理される場合、オプションを検討しません。
そして今、私は自分がどの松葉杖を使っているかを示したいと思います。
1)拡張
すべての区切り文字を同じにし、開始行を空にする必要があるとします。 次に、文字列の拡張関数を作成すると便利です。
public static class StringEx { public static string Append(this string main, string str, string delimiter) { if (string.IsNullOrEmpty(str) || string.IsNullOrEmpty(delimiter)) return main; else if (string.IsNullOrEmpty(main) || main.Trim() == "" || str.Trim() == "" || delimiter.Trim() == "") return str; else return main + delimiter + str; } }
2)ヘルパークラス
最後のフラグメントの前に特別なセパレーターを使用するために、拡張子は不要になり、ヘルパークラスを使用する必要があります。
class ListBuilder { bool first = true; string last = ""; string content = ""; string delimiter = ", "; string lastdelimiter = " and "; public ListBuilder() { } public ListBuilder(string delimiter, string lastdelimiter) { this.delimiter = delimiter ?? ", "; this.lastdelimiter = lastdelimiter ?? " and "; } public ListBuilder(string content, string delimiter, string lastdelimiter) { this.content = content ?? ""; this.delimiter = delimiter ?? ", "; this.lastdelimiter = lastdelimiter ?? " and "; } public void Append(string str) { if (str == null || str.Trim() == "") return; // if (first) { content += str; first = false; } // else { if (last != "") content += delimiter + last; last = str; } } public override string ToString() { if (last != "") return content + lastdelimiter + last; else return content; } }
使用例:
ListBuilder lb = new ListBuilder(" ", ", ", " "); foreach (string s in new string[] { "", "", "", "" }) lb.Append(s); // Console.WriteLine(lb + "!");
そして別の例:
ListBuilder lb = new ListBuilder(", , ", ", ", " "); if (!IsAutorized()) lb.Append(" "); if (!IsAdmin()) lb.Append(" "); if (!IsBadDay()) lb.Append(" "); if (!IsAutorized() || !IsAdmin() || !IsBadDay()) Console.WriteLine(lb + ".");
これが誰かに役立つか、少なくとも(少なくとも議論のために)面白いと思われることを願っています。
psはい、StringBuilderとIsNullOrWhiteSpaceの存在を知っています。 しかし、StringBuilderから多くを得ることはないので、コードを複雑にしないことにしました。 また、IsNullOrWhiteSpaceはフレームワークの4番目のバージョンから利用でき、松葉杖自体は3.5で開発されました。