如何在自己的方法中模仿 string.Format() 函数?

40

我有一个具有自定义的WriteLine(string)方法的对象。就像这样:

public void WriteLine(string text)
{
    this.StringList.Add(text);
}
什么是复制 string.Format() 功能的最简单方法?例如:我目前经常做的事情是:
myObj.WriteLine(string.Format("Hello, {0}", name));
如果您创建一个新的控制台应用程序,它们的WriteLine()方法正好做我想要做的事情:
Console.WriteLine("Hello, {0}", name);

它们消除了调用string.Format()的需要。是否可以轻松地使你的方法以某种方式接受这一点?或者我必须创建一千个方法重载?类似于这样:

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

这是唯一的逻辑方法吗?欢迎任何建议 :)


1
为什么不直接委托给 string.Format 呢?你真的想要编写一个分词器吗? - Oded
10
有关C#的一个特性,你可能还不知道,但需要了解。http://msdn.microsoft.com/zh-cn/library/w5zay9db(v=VS.100).aspx - Eric Lippert
@Oded 这就是我的问题... 我不知道 params 关键字,也不知道我甚至可以委托给 string.Format - Chev
没错,Alex - 我没有意识到那是问题的所在 :) - Oded
2
只是要小心参数;如果一个“params”方法在其正常形式下适用,则它不会以其扩展形式被调用。例如,“WriteLine(“”,null)”使用空数组调用WriteLine。“WriteLine(“”,(object)null)”使用包含单个null的数组调用WriteLine。 - Eric Lippert
3个回答

65
你需要从string.format中复制方法签名。
public void WriteLine(string text,params object[] args) {
  this.StringList.Add(string.Format(text,args));
}

正如ChaosPandion所建议的那样,您还可以包括重载以防止数组创建。

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));
}

我不会超过arg2,因为string.format并不会有所改善,所以这个好处就消失了。


太好了!在做一些乏味的事情之前,我很高兴花时间发布一个合适的问题。几乎总会有更好的方法。谢谢! - Chev
2
我会添加重载以避免对于简单情况的数组创建。也许最多4个参数。 - ChaosPandion
@ChaosPandion 好建议。我采纳了你的意见。 - Chev
为什么要使用StringList?而不是直接写入字符串? - Simple Fellow

8

有一个你可能想要避免的边缘情况。以下代码将把字符串{0}写入控制台。

Console.WriteLine("{0}");

然而,如果您使用其他答案中建议的WriteLine实现之一,这些实现将会抛出异常:
WriteLine("{0}"); //throws exception

最简单的解决方法是要么有两个WriteLine重载,要么稍微修改建议的代码来处理边缘情况:
public void WriteLine(string text,params object[] args) {
  var message=args.Length==0 ? text : string.Format(text, args);
  this.StringList.Add(message);
}

我已经为字符串设置了重载,所以这对我来说不是问题。谢谢你提醒我 :) - Chev

7

你可以使用参数

 public void WriteLine(string text, params object[] parameters)
 {
     //..
 }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接