Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

String.Format parameter order annoyance

it's really annoying how C# seems to force you to explicitly name the index of every parameter in String.Format, if you want to add another parameter somewhere you either have to re-index the string or put your new parameter at the end.

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

e.g. (I know this is pointless pedants, it's just an example :)

I 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)
like image 643
Jamie Kitson Avatar asked Sep 15 '09 11:09

Jamie Kitson


People also ask

What are format strings?

The Format String is the argument of the Format Function and is an ASCII Z string which contains text and format parameters, like: printf (“The magic number is: %d\n”, 1911); • The Format String Parameter, like %x %s defines the type of conversion of the format function.

Which of the format string is not valid?

Format string XXX is not a valid format string so it should not be passed to String.

What is the difference between string and format?

There's no difference in terms of the output it produces. The result variable will have the same contents in each case. But String. format() is there so that you can do more powerful formatting, including specifying number of decimal places for floating point numbers, and the like.

What is string literal in C#?

String literals or constants are enclosed in double quotes "" or with @"". A string contains characters that are similar to character literals: plain characters, escape sequences, and universal characters. You can break a long line into multiple lines using string literals and separating the parts using whitespaces.


3 Answers

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

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

like image 141
Jon Skeet Avatar answered Nov 13 '22 07:11

Jon Skeet


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

The code then 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.

like image 35
Sprotty Avatar answered Nov 13 '22 08:11

Sprotty


The function you request is not part of the framework. Here's a nice Extension Method I've found that provides named parameters c#. I think Marc Gravell posted it 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;
        });
    }
like image 31
Steve Avatar answered Nov 13 '22 09:11

Steve