views:

494

answers:

4

Hi,

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 reindex the string or put your new parameter at the end. Is there a way to get C# to do this automatically?

eg (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)

Cheers, Jamie

+19  A: 

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.

Jon Skeet
+1: Maintainability should always win over one off savings when originally writing.
Richard
+1 "Computer programs should be designed for humans to read and are incidentally run by computers"
Daniel Elliott
How about String.Format("{a} {b} {b} {c} {d}", a, b, c, d) ? Could this be added in .NET 4.0 ? Maybe compiler could help. Or new DLR ? I'm probably missing something here but it would be nice...
Petar Repac
IMHO readability is solved by putting the parameters on the next line.
Jamie Kitson
@Jamie: That doesn't solve readability at all. It doesn't make it any clearer which argument corresponds to which replacement token.
Jon Skeet
+1  A: 

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;
        });
    }
Steve
A: 

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

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

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

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

Thank you so much :) I needed this example

ilteriş MUTLU