String.Format annoyance order parameter

This is really annoying how C # seems to make you explicitly specify the index of each parameter in String.Format, if you want to add another parameter somewhere, you need to either reindex the string or add a new parameter to the end.

Is there a way to get C # to do this automatically?

eg. (I know that these are pointless pedants, this is just an example :)

I'll start with:

String.Format("{0} {1} {1} {2} {3}", a, b, c, d) 

If I want to add a parameter at the beginning, I can do one of the following:

 String.Format("{4} {0} {1} {1} {2} {3}", a, b, c, d, e) String.Format("{0} {1} {2} {2} {3} {4}", e, a, b, c, d) 

in Delphi, for example, I could do the equivalent of this:

 String.Format("{} {} {} {2} {} {}", e, a, b, c, d) 
+6
string c # formatting
source share
5 answers

Well, there is nothing in C # to do this automatically for you. You can always write your own method, but to be honest, I would find it less readable. You need to think a lot more (IMO) to understand what your last line is doing than the previous one. When you click on {2} , you need to go back and replace the previous element {3} to skip {2} , etc.

Personally, I prefer code that takes a little longer to enter but is clear to read.

+23
source share

As with Visual Studio 2015, you can work around this problem using Interpolated Strings (this is a compiler trick, so it doesn't matter which version of the .net framework you are targeting).

Then the code looks something like this:

 string txt = $"{person.ForeName} is not at home {person.Something}"; 

I think it makes the code more readable and less error prone.

+3
source share

The function you requested is not part of the framework. Here is a good extension method I found that provides C # named parameters. I think Mark Gravell wrote this or one of those other SO gurus.

  static readonly Regex rePattern = new Regex(@"\{([^\}]+)\}", RegexOptions.Compiled); /// <summary> /// Shortcut for string.Format. Format string uses named parameters like {name}. /// /// Example: /// string s = Format("{age} years old, last name is {name} ", new {age = 18, name = "Foo"}); /// /// </summary> /// <param name="format"></param> /// <param name="values"></param> /// <returns></returns> public static string FN<T>(this string pattern, T template) { Dictionary<string, string> cache = new Dictionary<string, string>(); return rePattern.Replace(pattern, match => { string key = match.Groups[1].Value; string value; if (!cache.TryGetValue(key, out value)) { var prop = typeof(T).GetProperty(key); if (prop == null) { throw new ArgumentException("Not found: " + key, "pattern"); } value = Convert.ToString(prop.GetValue(template, null)); cache.Add(key, value); } return value; }); } 
+2
source share

Even if C # cannot do this for you, the tool can help here.

Resharper, for example, warns you if there are more parameters in a line than after a line. I looked to see if parameter reordering is supported in Resharper, but in this case it is not (R # supports replacing the method signature, but this does not help here).

Look at the Rush code from DevEx. This tool probably has what you need.

+1
source share

I know this is old, I agree with John. Even with a large format string (see code sample below) it still takes me less than 1 minute to repeat the location of the element pointers, if I need to add something, and I find it more convenient and easy to read, and then try to create process automation method. The problem with automation for this is when I try to take a look at the code after a few weeks .. you cannot just figure it out at a glance. In addition, once you have a good look at Visual Studio and learn how to use things like block editing mode and some other advanced features, you can be quite productive.

 //----------------------------------------------------------------------------- // <copyright file="ShellForm.cs" company="DCOM Productions"> // Copyright (c) DCOM Productions. All rights reserved. // </copyright> //----------------------------------------------------------------------------- string updateCommandText = string.Format("UPDATE `moh`.`moh` SET ageact = '{0}', branch = '{1}', cemetary = '{2}', citation = '{3}', citycement = '{4}', cdateact = '{5}', cdateaward = '{6}', cdatebirth = '{7}', cdatedeath = '{8}', namefirst = '{9}', namelast = '{10}', placeact = '{11}', placeenter = '{12}', presat = '{13}', presby = '{14}', rankact = '{15}', rankawd = '{16}', rankhigh = '{17}', synopsis = '{18}', unit = '{19}', war = '{20}', imgfile = '{21}' WHERE ID = '{22}'", /* {0} */ uxAgeAct.Text.Replace("'", "''"), /* {1} */ uxBranch.Text.Replace("'", "''"), /* {2} */ uxCemetary.Text.Replace("'", "''"), /* {3} */ uxCitation.Text.Replace("'", "''"), /* {4} */ uxCityCemetary.Text.Replace("'", "''"), /* {5} */ uxDateAct.Text.Replace("'", "''"), /* {6} */ uxDateAward.Text.Replace("'", "''"), /* {7} */ uxDateBirth.Text.Replace("'", "''"), /* {8} */ uxDateDiceased.Text.Replace("'", "''"), /* {9} */ uxNameFirst.Text.Replace("'", "''"), /* {10} */ uxNameLast.Text.Replace("'", "''"), /* {11} */ uxPlaceAct.Text.Replace("'", "''"), /* {12} */ uxPlaceEnter.Text.Replace("'", "''"), /* {13} */ uxPresentedAt.Text.Replace("'", "''"), /* {14} */ uxPresentedBy.Text.Replace("'", "''"), /* {15} */ uxRankAct.Text.Replace("'", "''"), /* {16} */ uxRankAwarded.Text.Replace("'", "''"), /* {17} */ uxRankHigh.Text.Replace("'", "''"), /* {18} */ uxSynopsis.Text.Replace("'", "''"), /* {19} */ uxUnit.Text.Replace("'", "''"), /* {20} */ uxWar.Text.Replace("'", "''"), /* {21} */ uxImgFile.Text.Replace("'", "''"), /* {22} */ dataRow["ID"].ToString()); 
+1
source share

All Articles