📜 ⬆️ ⬇️

Minicostilles: glue a string of fragments

Many people probably know the problem, which they often decide to quickly: add a fragment to the line if the next condition is fulfilled.

A typical piece of code (a slightly contrived example, but still):
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); //... } 

At the output, if all the arguments are zero, we get the string "ARG1 ARG2 ARG3" .
And if we want "ARG1 , ARG2 , ARG3" ? Or even "ARG1 , ARG2 and ARG3" ?

In this case, very often (if you do not use a special separator before the last word) use the following solution:
 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); //... } 
In other words, put a separator after each word, and then “bite off” an extra separator at the end of the line.

There is also a small variation of the same method, when an “extra” argument is added to the beginning of the line and now the separator is written BEFORE another fragment. Plus the one that does not need to cut off anything from the end of the line. Below is one of the examples when using this approach:
 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; } 
Options, when all sorts of combinations of conditions are being recruited, I, for obvious reasons, will not consider.
')
And now, I want to show what crutches I use myself:

1) Expansion

Suppose that all delimiters must be the same and the initial line must be empty. Then it will be convenient to write an extension function for the string:
 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) Auxiliary class

In order to use a special separator before the last fragment, the extension is not enough and you will have to use an auxiliary class:
 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; } } 

Example of use:

 ListBuilder lb = new ListBuilder("  ", ", ", "  "); foreach (string s in new string[] { "", "", "", "" }) lb.Append(s); //  Console.WriteLine(lb + "!"); 

And another example:

 ListBuilder lb = new ListBuilder(",  ,   ", ", ", "   "); if (!IsAutorized()) lb.Append("  "); if (!IsAdmin()) lb.Append("  "); if (!IsBadDay()) lb.Append("  "); if (!IsAutorized() || !IsAdmin() || !IsBadDay()) Console.WriteLine(lb + "."); 

I hope someone will find this useful or at least interesting (at least for discussion).

ps Yes, I know about the existence of StringBuilder and IsNullOrWhiteSpace. But there’s not much to get a big win from StringBuilder, so I decided not to complicate the code. And IsNullOrWhiteSpace is available from the 4th version of the framework, and the crutches themselves were invented for 3.5 more.

Source: https://habr.com/ru/post/133805/


All Articles