Named string formatting in C#

Solution 1:

There is no built-in method for handling this.

Here's one method

string myString = "{foo} is {bar} and {yadi} is {yada}".Inject(o);

Here's another

Status.Text = "{UserName} last logged in at {LastLoginDate}".FormatWith(user);

A third improved method partially based on the two above, from Phil Haack

Solution 2:

I have an implementation I just posted to my blog here: http://haacked.com/archive/2009/01/04/fun-with-named-formats-string-parsing-and-edge-cases.aspx

It addresses some issues that these other implementations have with brace escaping. The post has details. It does the DataBinder.Eval thing too, but is still very fast.

Solution 3:

Interpolated strings were added into C# 6.0 and Visual Basic 14

Both were introduced through new Roslyn compiler in Visual Studio 2015.

  • C# 6.0:

    return "\{someVariable} and also \{someOtherVariable}" OR
    return $"{someVariable} and also {someOtherVariable}"

    • source: what's new in C#6.0

       

  • VB 14:

    return $"{someVariable} and also {someOtherVariable}"

    • source: what's new in VB 14

Noteworthy features (in Visual Studio 2015 IDE):

  • syntax coloring is supported - variables contained in strings are highlighted
  • refactoring is supported - when renaming, variables contained in strings get renamed, too
  • actually not only variable names, but expressions are supported - e.g. not only {index} works, but also {(index + 1).ToString().Trim()}

Enjoy! (& click "Send a Smile" in the VS)

Solution 4:

You can also use anonymous types like this:

    public string Format(string input, object p)
    {
        foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(p))
            input = input.Replace("{" + prop.Name + "}", (prop.GetValue(p) ?? "(null)").ToString());

        return input;
    }

Of course it would require more code if you also want to parse formatting, but you can format a string using this function like:

Format("test {first} and {another}", new { first = "something", another = "something else" })

Solution 5:

There doesn't appear to be a way to do this out of the box. Though, it looks feasible to implement your own IFormatProvider that links to an IDictionary for values.

var Stuff = new Dictionary<string, object> {
   { "language", "Python" },
   { "#", 2 }
};
var Formatter = new DictionaryFormatProvider();

// Interpret {0:x} where {0}=IDictionary and "x" is hash key
Console.WriteLine string.Format(Formatter, "{0:language} has {0:#} quote types", Stuff);

Outputs:

Python has 2 quote types

The caveat is that you can't mix FormatProviders, so the fancy text formatting can't be used at the same time.