比较
String.Format("Hello {0}", "World");
与
"Hello {0}".Format("World");
为什么 .Net 设计者选择使用静态方法而不是实例方法?您的看法是什么?
我不知道他们为什么这样做,但现在已经不重要了:
public static class StringExtension
{
public static string FormatWith(this string format, params object[] args)
{
return String.Format(format, args);
}
}
public class SomeClass
{
public string SomeMethod(string name)
{
return "Hello, {0}".FormatWith(name);
}
}
当你有一个维护某些状态的对象时,实例方法是很好的选择;格式化字符串的过程不会影响你正在操作的字符串(即不会修改其状态),而是创建一个新的字符串。
使用扩展方法,你现在可以既拥有自己想要的语法,又能达到目的(即如果它能帮助你晚上睡得更好,你可以使用后一种语法)。
我认为使用String.Format通常会更好,但如果您已经有一个存储在变量中要“格式化”的字符串,则希望具有非静态函数的点也是可以理解的。
顺便说一下,字符串类的所有函数都不作用于字符串本身,而是返回一个新的字符串对象,因为字符串是不可变的。
@Jared:
不重载,不继承的静态方法(例如Class.b(a,c))将实例作为第一个变量,与方法调用(例如a.b(c))在语义上是等效的。
不,它们并不等价。
(假设它编译成相同的CIL,应该是这样。)
这是你的错误。生成的CIL是不同的。区别在于成员方法不能在null
值上调用,因此CIL会插入对null
值的检查。而静态方法则没有这个操作。
然而,String.Format
不允许null
值,所以开发人员必须手动插入检查。从这个角度来看,成员方法变体在技术上更优。
String.Format
的原因是与C语言中的printf
函数相似。它旨在让C开发人员更容易地切换语言。
我认为将其设置为静态的没有任何问题。
静态方法的语义对我来说更有意义。也许是因为它是一个原始类型。当经常使用原始类型时,您希望使用与它们一起工作的实用程序代码尽可能轻巧。此外,我认为使用 String.Format 要比 "MyString BLAH BLAH {0}".Format 更好。
"my {0} string".Format(args)
,它增加了长度,并且使得将字符串字面量转换为格式化字符串变得更加复杂。虽然不是很多,但足够使用实例方法来简化操作。 - ehdv我还没有尝试过,但你可以为你想要的内容创建一个扩展方法。我不会这样做,但我认为它会起作用。
另外,我发现String.Format()
更符合其他模式化静态方法的风格,比如Int32.Parse()
、long.TryParse()
等。
如果你想要一个非静态格式,你也可以使用StringBuilder
。
StringBuilder.AppendFormat()
非重载,非继承的静态方法(例如Class.b(a,c))将实例作为第一个变量,语义上等同于方法调用(例如a.b(c)),因此平台团队做出了任意的审美选择。(假设编译成相同的CIL,应该是这样。)唯一的方法是询问他们为什么。
可能是为了让这两个字符串在字典排序中保持接近,即
String.Format("Foo {0}", "Bar");
替代
"Foo {0}".Format("bar");
你想知道索引映射到什么;也许他们认为“.Format”部分只是在中间添加噪音。
有趣的是,ToString方法(至少针对数字)相反:number.ToString(“000”),格式字符串在右侧。
String.Format
至少需要一个字符串并返回另一个字符串。它不需要修改格式字符串以返回另一个字符串,因此这样做(忽略其格式)没有太多意义。另一方面,将 String.Format
设为成员函数也不是那么困难,只是我认为 C# 不允许像 C++ 那样的常量成员函数。如果我错了,请纠正我和这篇文章。
String.Format
是静态的,而像Trim
和PadLeft
这样的其他方法不是静态的是不一致的。 - Alex Lowe