user153923
user153923

Reputation:

How Would I write a String.Format Extension Method?

I use String.Format in my C# code probably more than anything aside from the if statement.

string ask = String.Format("Continue using [{0}]?", value);

I just got to thinking of how often I use it.

Next, I got to thinking of how great it would be to create an Extension Method for it.

ask.Format("Continue using [{0}]?", value);

So, I got to looking at String.Format, and it has many overloads because there are many ways that it could be called.

Hmmm... That complicates things.

Would there be a simple way of writing an Extension Method that simply builds on the overloads already existing in the System.String namespace?

Here is what I would like to see:

public static class Extensions
{
  public static String Format(this String str, String formatText, /* What goes here? */)
  {
    return str.Format(formatText, /* Magic */);
  }
}

I suppose I could write an overload to match each of the String.Format overloads, but that may not be necessary.

Upvotes: 2

Views: 7181

Answers (4)

Joel Coehoorn
Joel Coehoorn

Reputation: 416059

You want to modify the calling string. You can't do that. Strings in .Net do not change (they are immutable), and so you would still have to return a new string. The closest you can get from C# is code like this:

string ask = $"Continue using [{value}]?";

It would be possible to modify your original string if you could pass the extension object by reference. Unfortunately, C# does not support this.

What's interesting is that the IL does support it, and you could write the method you wanted using VB.Net:

<Extension()> _
Public Shared Sub Format(ByRef str As String, ByVal formatText As String, ByVal ParamArray args As Object())
    str = String.Format(formatText, args);
End Sub

Unfortunately, even if you stuff this in a VB.Net class library project, you wouldn't be able to call it from C#, because C# requires you to use the ref keyword at the call site when calling functions with parameters by reference, and there is no syntax for this with an extension method.

For a work-around that doesn't exactly match your desired syntax, but will still give you something pretty nice, see Mike Cole's answer.

Upvotes: 2

Sam
Sam

Reputation: 922

Use string interpolation (in C# 6.0 and VS 2015+). Your code would look like this:

var ask = $"Continue using [{value}]?";

I had been using either String.Format or string concatenation until I discovered string interpolation and now I'm hooked.

One potential downside to this is that you can't factor out your format strings to constants or resources. Have a look here for more details:

https://msdn.microsoft.com/en-us/library/dn961160.aspx

This article goes into more details and includes some other nice gems. Definitley worth a read:

https://msdn.microsoft.com/en-us/magazine/dn879355.aspx

Upvotes: 1

Mike Cole
Mike Cole

Reputation: 14733

ask.Format("Continue using [{0}]?", value);

is not how I would use it. Here's what I would do:

var ask = "Continue using [{0}]?".FormatWith(value);

And here's my extension method:

public static string FormatWith(this string value, params object[] args)
{
    return String.Format(value, args);
}

Upvotes: 20

Adriano Carneiro
Adriano Carneiro

Reputation: 58615

You were close, missing only the params object[] args parameter:

public static class Extensions
{
  public static String Format(this String str, 
                              String formatText, 
                              params object[] args)
  {
    return str.Format(formatText, args);
  }
}

Upvotes: 1

Related Questions