为什么是String.Format静态?

比较

String.Format("Hello {0}", "World"); 

 "Hello {0}".Format("World"); 

.Netdevise者为什么select一个实例方法的静态方法? 你怎么看?

我实际上并不知道答案,但我怀疑这与直接在string文字上调用方法有关。

如果我记得正确(我没有真正validation这一点,因为我没有旧的IDE方便),早期版本的C#IDE无法检测IntelliSense中针对string文字的方法调用,并且对可发现性有很大的影响的API。 如果是这种情况,input以下内容将不会给你任何帮助:

 "{0}".Format(12); 

如果你被迫打字

 new String("{0}").Format(12); 

很明显,使Format方法成为实例方法而不是静态方法没有什么好处。

.NET库是由许多给了我们MFC的人所devise的,特别是String类与MFC中的CString类非常相似。 MFC有一个实例Format方法(使用printf风格格式代码而不是.NET的花括号风格),这是很痛苦的,因为没有像CString文字那样的东西。 所以在我工作的MFC代码库中,我看到了很多:

 CString csTemp = ""; csTemp.Format("Some string: %s", szFoo); 

这是痛苦的。 (我并不是说上面的代码是在MFC中做事情的好方法,但是似乎大多数项目开发人员学习了如何使用CString :: Format)。 从这个传统来看,我可以想象APIdevise者正试图避免这种情况。

因为Format方法与string的当前值无关。

所有string方法都是如此,因为.NETstring是不可变的。

如果它是非静态的,你将需要一个string开始。

它确实:格式string。

我相信这只是.NET平台中许多devise缺陷的另一个例子(我并不认为这是一个火焰;我仍然发现.NET框架优于大多数其他框架)。

那么我想你必须对它有特别的了解,但是正如人们所说,由于隐含的语义,String.Format是静态的。 考虑:

 "Hello {0}".Format("World"); // this makes it sound like Format *modifies* // the string, which is not possible as // strings are immutable. string[] parts = "Hello World".Split(' '); // this however sounds right, // because it implies that you // split an existing string into // two *new* strings. 

当我升级到VS2008和C#3时,我做的第一件事是做到这一点

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

所以我现在可以改变我的代码

 String.Format("Hello {0}", Name); 

 "Hello {0}".F(Name); 

这是我当时的首选。 如今(2014年),我不打扰,因为这只是另一个麻烦,不断重复添加到我创build的每个随机项目,或者链接到一些应用程序库。

至于为什么.NETdevise师select了它? 谁知道。 这看起来完全是主观的。 我的钱也是

  • 复制Java
  • 当时写的那个人主观上更喜欢它。

我找不到任何其他有效的理由

我认为这是因为Format本身并不是一个string,而是一个“格式string”。 大多数string与“Bob Smith”或“1010 Main St”等相同,或者“Hello {0}”不等于“Hello {0}”,通常只有在尝试使用模板创build其他string时string,就像工厂方法一样,因此它将自己借给一个静态方法。

我认为这是因为它是一个创造者的方法(不知道是否有一个更好的名字)。 它所做的就是把你给它的东西,并返回一个单一的string对象。 它不在现有对象上运行。 如果它是非静态的,你将需要一个string开始。

因为Format方法与string的当前值无关。 string的值不被使用。 它需要一个string并返回一个。

也许.NETdevise师这样做,因为JAVA这样做…

拥抱和延伸。 🙂

请参阅: http : //discuss.techinterview.org/default.asp?joel.3.349728.40

.NETstring是不可变的
因此有一个实例方法是绝对没有意义的。

通过这个逻辑,string类应该没有实例方法返回对象的修改副本,但它有很多 (修剪,ToUpper,等等)。 此外,框架中的许多其他对象也是这样做的。

我同意,如果他们把它作为一个实例方法, Format似乎是一个坏名字,但这并不意味着function不应该是一个实例方法。

为什么不呢? 这与.NET框架 的其余部分是一致的

 "Hello {0}".ToString("Orion"); 

当你有一个对象保持某种状态时,实例方法是很好的; 格式化string的过程不会影响您正在操作的string(请参阅:不修改其状态),它会创build一个新的string。

有了扩展方法,你现在可以吃你的蛋糕,也可以吃它(也就是说,如果它可以帮助你在晚上睡得更好,你可以使用后面的语法)。

我认为使用String.Format看起来更好一些,但是当你已经有一个string存储在你想要“格式化”的variables的时候,我可能会想要一个非静态函数。

另外,string类的所有函数都不会对string起作用,而是返回一个新的string对象,因为string是不可变的。

@Jared:

非重载,非inheritance静态方法(如Class.b(a,c))将实例作为第一个variables在语义上等同于方法调用(如ab(c))

不,他们不是。

(假设它编译为相同的CIL,它应该)。

这是你的错误。 所产生的CIL是不同的。 区别在于成员方法不能在null值上调用,所以CIL插入一个针对null值的检查。 这显然不是在静态variables中完成的。

但是, String.Format不允许null值,因此开发人员必须手动插入检查。 从这个angular度来看,成员方法变体在技术上会更胜一筹。

这是为了避免与.ToString()方法混淆。

例如:

 double test = 1.54d; //string.Format pattern string.Format("This is a test: {0:F1}", test ); //ToString pattern "This is a test: " + test.ToString("F1"); 

如果Format是string的一个实例方法,这可能会导致混淆,因为这些模式是不同的。

String.Format()是将多个对象转换为格式化string的实用程序方法。

一个string的实例方法对该string做了一些事情。

当然,你可以这样做:

 public static string FormatInsert( this string input, params object[] args) { return string.Format( input, args ); } "Hello {0}, I have {1} things.".FormatInsert( "world", 3); 

我不知道他们为什么这样做,但是这并不重要:

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

恕我直言,这stream动很容易。

C#的一个大devise目标是尽可能简单地从C / C ++转换到C / C ++。 在string上使用点语法对于只有C / C ++背景的人来说看起来奇怪,格式化string是开发人员在第一天就可以使用的语言。 所以我相信他们把它变成静态的,使它更接近熟悉的领域。

String.Format必须是一个静态方法,因为string是不可变的。 使其成为实例方法意味着可以使用它来“格式化”或修改现有string的值。 这是你不能做的,并且使它成为返回新string的实例方法将是没有意义的。 因此,这是一个静态的方法。

String.Format另一个原因是与C函数printf的相似之处。它应该让C开发人员有一个更容易的时间切换语言。

我没有看到它是静态的错误..

静态方法的语义似乎对我来说更有意义。 也许这是因为它是一个原始的。 在原始语言常用的地方,你想要使用它们的实用代码尽可能的轻。另外,我认为在“MyString BLAH BLAH {0}”上使用String.Format的语义更好。 ..

非重载非静态方法(如Class.b(a,c))将实例作为第一个variables在语义上等同于方法调用(如ab(c)),因此平台团队进行了任意的,美学select。 (假设它编译到相同的CIL,它应该。)唯一的方法知道将是问他们为什么。

可能他们是这样做的,以保持两个string彼此靠近,即

 String.Format("Foo {0}", "Bar"); 

代替

 "Foo {0}".Format("bar"); 

你想知道索引映射到什么; 也许他们认为“.Format”部分只是在中间增加了噪音。

有趣的是,ToString方法(至less对于数字)是相反的:number.ToString(“000”),格式string在右侧。

我还没有尝试过,但你可以做一个你想要的扩展方法。 我不会这样做,但我认为这会奏效。

此外,我发现String.Format()更符合其他图案的静态方法,如Int32.Parse()long.TryParse()

如果你想要一个非静态的格式,你也可以使用StringBuilderStringBuilder.AppendFormat()

.NETstring是不可变的

因此有一个实例方法是绝对没有意义的。

 String foo = new String(); foo.Format("test {0}",1); // Makes it look like foo should be modified by the Format method. string newFoo = String.Format(foo, 1); // Indicates that a new string will be returned, and foo will be unaltered. 

String.Format至less需要一个String并返回一个不同的String。 它不需要修改格式string来返回另一个string,所以这样做是没有意义的(忽略你的格式)。 另一方面,除了我不认为C#允许像C ++这样的const成员函数外,将String.Format作为成员函数并不是那么简单。 [请纠正我和这个post,如果它。]