String.Format () - Repeating parameters, but adding additional parameters

I would like to do something like this:

public string GetMessage(params object otherValues[]) { return String.Format(this.Message, this.FirstValue, otherValues); } 

So, I would like to pass an array of parameters to String.Format() , but adding a new parameter.

What would be the best way to do this, knowing that we can "rebuild" a new array of objects, and this does not seem good.

+6
source share
6 answers
 public string GetMessage(params object[] otherValues) { return String.Format(this.Message, new[] { this.FirstValue }.Concat(otherValues).ToArray<object>()); } 
+15
source

You can use Concat and ToArray extension methods:

 public string GetMessage(params object[] otherValues) { var values = new[] { this.FirstName }.Concat(otherValues).ToArray(); return String.Format(this.Message, values); } 
+3
source

If there are often several other parameters, I would use existing overloads:

 public string GetMessage(params object[] otherValues) { if (otherValues == null) return string.Format(this.Message, this.FirstValue); switch (otherValues.Length) { case 0: return string.Format(this.Message, this.FirstValue); case 1: return string.Format(this.Message, this.FirstValue, otherValues[0]); case 2: return string.Format(this.Message, this.FirstValue, otherValues[0], otherValues[1]); default: return string.Format(this.Message, new[] { this.FirstValue }.Concat(otherValues).ToArray()); } } 
+1
source

Preprocess message

If you do not want to create a new array in each call to GetMessage (...), you can insert FirstValue into the message at the beginning once at a time , and then GetMessage (...) just uses the otherValues ​​parameter for string.Format (. ..).

The Message property is initialized after setting FirstValue, for example. in the constructor or in the init method like this:

 void InitMessage() { Message = String.Format(Message, FirstValue, "{0}", "{1}", "{2}", "{3}", "{4}"); } 

The InitMessage method initializes the first index in Message with FirstValue, and the remaining indexes with "{index}", that is, "{0}", "{1}", "{2}", ... (This is allowed to have more params elements than post indices).

Now GetMessage can call String.Format without any array operations:

 public string GetMessage(params object[] otherValues) { return String.Format(Message, otherValues); } 

Example:

Assume the following property values:
this.Message = "First value is '{0}'. Other values are '{1}' and '{2}'." and this.FirstValue = "blue" .

Changes to InitMessage Message to:
"First value is 'blue'. Other values are '{0}' and '{1}'." .

GetMessage Request
GetMessage("green", "red")

results

"First value is 'blue'. Other values are 'green' and 'red'." .

+1
source

Another messy way is to hack formatting with RegEx if you really can't create another structure for the array.

 private string FormatEval(Match m) { int val = -1; string formatted = m.Value; if (int.TryParse(m.Groups["index"].Value, out val)) formatted = val == 0 ? this.FirstValue : "{" + (val - 1).ToString() + "}"; return formatted; } public string GetMessage(params object[] otherValues) { string format = Regex.Replace(this.Message, @"\{(?<index>\d+)\}", FormatEval); return string.Format(format, otherValues); } 

Basically, just parse the format string for formatting tokens ({0}, {1}), etc. And decrease their index. If the token is {0} initially, replace it with the string this.FirstName.

Essentially, this is executing the first step of String.Format manually, and then passing the resulting string to the REAL String.Format method to complete.

0
source

Skip Discrete Items

To avoid creating an array in a GetMessage Everey call, you can pass otherValues ​​with your discrete elements:

 public string GetMessage(params object[] otherValues) { return String.Format(Message, FirstValue, GetOrDefault(otherValues, 0), GetOrDefault(otherValues, 1), GetOrDefault(otherValues, 2), GetOrDefault(otherValues, 3), GetOrDefault(otherValues, 4)); } private object GetOrDefault(object[] otherValues, int index) { if (otherValues == null) return null; if (index < otherValues.Length) return otherValues[index]; return null; } 
0
source

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


All Articles