[ACCEPTED]-String.Format parameter order annoyance-formatting

Accepted answer
Score: 25

Well, there's nothing in C# to do this automatically 10 for you. You could always write your own 9 method to do it, but frankly I'd find it 8 less readable. There's a lot more thinking 7 to do (IMO) to understand what your final 6 line does than the previous one. When you 5 hit the {2} you've got to mentally backtrack 4 and replace the previous item with {3} to skip 3 the {2} etc.

Personally I prefer code which 2 takes a bit longer to type, but is clear 1 to read.

Score: 5

As of Visual Studio 2015 you can side step 5 this issue using Interpolated Strings (its a compiler trick, so 4 it doesn't matter which version of the .net 3 framework you target).

The code then looks 2 something like this

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

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

Score: 2

The function you request is not part of 4 the framework. Here's a nice Extension Method 3 I've found that provides named parameters 2 c#. I think Marc Gravell posted it or one 1 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;
        });
    }
Score: 1

Even though C# can't do this for you, the 8 tool could help here.

Resharper for example 7 warns you if you have more parameters in 6 the string than after the string. I looked 5 if parameter reordering in Resharper is 4 supported but in this case it isn't (R# supports 3 changing method signature but that doesn't 2 help here).

Look at Code Rush from DevEx. That 1 tool very likely has what you need.

Score: 1

I know this is old, I agree with Jon. Even 13 with a large format string (see code example 12 below), it still only takes me less then 11 1 minute to redo the index locations of 10 the items if I have to add something, and 9 I find it more maintainable and readable 8 then trying to create a method to automate 7 the process. The problem with automation 6 for this is when I try to look at the code 5 a few weeks later.. you cannot just figure 4 it out at first glance. Also, once you learn 3 Visual Studio well and learn to use things 2 like block edit mode, and some of the other 1 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());

More Related questions