40

I have an object with a custom WriteLine(string) method. Something like this:

public void WriteLine(string text)
{
    this.StringList.Add(text);
}

What is the easiest way to duplicate the functionality of string.Format() with this method? For example: What I currently often find myself doing is this:

myObj.WriteLine(string.Format("Hello, {0}", name));

If you create a new Console application their version of a WriteLine() method does exactly what I would prefer to do:

Console.WriteLine("Hello, {0}", name);

They eliminate the need to call string.Format(). Is it easy to make your method accept this somehow? Or am I going to have to create a thousand method overloads? Something like this:

public void WriteLine() { ... }

public void WriteLine(string text) { ... }

public void WriteLine(string text, object arg0) { ... }

public void WriteLine(string text, object arg0, object arg1) { ... }

public void WriteLine(string text, object arg0, object arg1, object arg2)
{
    this.StringList.Add(string.Format(text, arg0, arg1, arg2));
}

// etc etc etc

Is that the only logical way to do this? Any suggestions are welcomed :)

CatDadCode
  • 58,507
  • 61
  • 212
  • 318
  • 1
    Why not just delegate to `string.Format`? Do you really want to write a tokenizer? – Oded Sep 14 '11 at 19:50
  • 10
    There's a feature of C# that you don't know about that you need to know about. http://msdn.microsoft.com/en-us/library/w5zay9db(v=VS.100).aspx – Eric Lippert Sep 14 '11 at 19:52
  • @Oded that's my question... I was unaware of the `params` keyword and did not know that I even ***could*** delegate to `string.Format`. – CatDadCode Sep 14 '11 at 19:55
  • Fair enough Alex - I didn't realize that was the issue :) – Oded Sep 14 '11 at 19:56
  • 2
    Just be careful with params; if a "params" method is applicable in its *normal* form then it is not called in its *expanded* form. For example, "WriteLine("", null)" calls WriteLine *with a null array*. "WriteLine("", (object)null)" calls WriteLine with an array containing a single null. – Eric Lippert Sep 14 '11 at 19:58

3 Answers3

65

You need to copy the method signature from string.format.

public void WriteLine(string text,params object[] args) {
  this.StringList.Add(string.Format(text,args));
}

As suggested by ChaosPandion you can also include overloads to prevent array creation

public void WriteLine(string text) {
  this.StringList.Add(text);
}

public void WriteLine(string text,object arg0) {
  this.StringList.Add(string.Format(text, arg0));
}

public void WriteLine(string text,object arg0, object arg1) {
  this.StringList.Add(string.Format(text, arg0, arg1));
}

public void WriteLine(string text,object arg0, object arg1, object arg2) {
  this.StringList.Add(string.Format(text, arg0, arg1, arg2));
}

I wouldn't go past arg2 as string.format doesn't so the benefit disappears.

Bob Vale
  • 18,094
  • 1
  • 42
  • 49
8

There is one edge case you might want to take pains to avoid. The following code will write the string {0} to the console

Console.WriteLine("{0}");

However, you use one of the implementations of WriteLine suggested by others in this answer, those implementations will throw an exception:

WriteLine("{0}"); //throws exception

The easiest fix is either to have two overloads of WriteLine or to modify the suggested code slightly to handle the edge case:

public void WriteLine(string text,params object[] args) {
  var message=args.Length==0 ? text : string.Format(text, args);
  this.StringList.Add(message);
}
Corey Kosak
  • 2,615
  • 17
  • 13
  • I already had an overload for just string so that is not a problem for me. Thanks for calling attention to that :) – CatDadCode Sep 14 '11 at 22:12
7

You could use params:

 public void WriteLine(string text, params object[] parameters)
 {
     //..
 }
BrokenGlass
  • 158,293
  • 28
  • 286
  • 335