ミニカット:断片の文字列を接着する

おそらく多くの人々がこの問題に精通しており、多くの場合、急いで解決されます。次の条件が満たされた場合、回線にフラグメントを追加します。



典型的なコード(やや不自然な例ですが、それでも):

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で開発されました。



All Articles