相比

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

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

为什么.Net设计者选择静态方法而不是实例方法? 你怎么看?

===============>>#1 票数:48

因为Format方法与字符串的当前值无关。

对于所有字符串方法都是如此,因为.NET字符串是不可变的。

如果它是非静态的,则需要一个字符串开头。

它确实:格式字符串。

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

===============>>#2 票数:28 已采纳

我实际上并不知道答案,但我怀疑它与直接调用字符串文字的方法有关。

如果我没记错的话(我实际上没有验证这个,因为我没有旧的IDE方便),早期版本的C#IDE无法在IntelliSense中检测针对字符串文字的方法调用,这对可发现性有很大影响的API。 如果是这种情况,键入以下内容将不会给您任何帮助:

"{0}".Format(12);

如果你被迫打字

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

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

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

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

这很痛苦。 (我不是说上面的代码即使在MFC中也是很好的做法,但这似乎是项目中大多数开发人员学习如何使用CString :: Format的方式)。 基于这种传统,我可以想象API设计者试图再次避免这种情况。

===============>>#3 票数:9

好吧,我想你必须要特别注意它,但就像人们所说的那样,由于隐含的语义,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.

===============>>#4 票数:8

当我升级到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)我不打扰因为再次添加到我创建的每个随机项目或链接到一些bag-of-utils库中只是另一个麻烦。

至于.NET设计师选择它的原因是什么? 谁知道。 这似乎完全是主观的。 我的钱也在

  • 复制Java
  • 当时写这篇文章的人主观地喜欢它。

我找不到任何其他正当理由

===============>>#5 票数:6

我认为这是因为Format本身不接受字符串,而是“格式字符串”。 大多数字符串都等于“Bob Smith”或“1010 Main St”之类的东西或者你有什么而不​​是“Hello {0}”,通常你只是在尝试使用模板创建另一个时才放入那些格式字符串。字符串,就像工厂方法一样,因此它将自己赋予静态方法。

===============>>#6 票数:4

我认为这是因为它是一种创造者方法(不确定是否有更好的名字)。 它所做的就是拿你给它的东西并返回一个字符串对象。 它不对现有对象进行操作。 如果它是非静态的,则需要一个字符串开头。

===============>>#7 票数:4

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

===============>>#8 票数:4

也许.NET设计师这样做是因为JAVA这样做了......

拥抱和延伸。 :)

见: http//discuss.techinterview.org/default.asp?joel.3.349728.40

===============>>#9 票数:3

.NET字符串是不可变的
因此,使用实例方法绝对没有意义。

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

我同意,如果他们要使它成为一个实例方法, Format看起来好像是一个坏名字,但这并不意味着该功能不应该是一个实例方法。

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

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

===============>>#10 票数:2

当你有一个维持某种状态的对象时,实例方法很好; 格式化字符串的过程不会影响您正在操作的字符串(读取:不修改其状态),它会创建一个新字符串。

使用扩展方法,您现在可以吃蛋糕并吃掉它(即如果它可以帮助您在晚上睡得更好,则可以使用后一种语法)。

===============>>#11 票数:2

我认为使用String.Format一般看起来更好,但是当你已经将一个字符串存储在你想要“格式化”的变量中时,我可以看到想要拥有非静态函数的一点。

顺便说一下,字符串类的所有函数都不会对字符串起作用,而是返回一个新的字符串对象,因为字符串是不可变的。

===============>>#12 票数:2

@Jared:

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

不,他们不是。

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

那是你的错。 产生的CIL是不同的。 区别在于无法在null值上调用成员方法,因此CIL会对null值插入检查。 这显然不是在静态变体中完成的。

然而, String.Format 不允许 null值,所以开发人员必须手动插入一张支票。 从这个角度来看,成员方法变体在技术上是优越的。

===============>>#13 票数:2

这是为了避免与.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.Format()是一种将多个对象转换为格式化字符串的实用程序方法。

字符串上的实例方法对该字符串执行某些操作。

当然,你可以这样做:

public static string FormatInsert( this string input, params object[] args) {
    return string.Format( input, args );
}

"Hello {0}, I have {1} things.".FormatInsert( "world", 3);

===============>>#14 票数:2

我不知道他们为什么这样做,但它不再重要了:

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

恕我直言,这更容易流动。

===============>>#15 票数:2

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

===============>>#16 票数:2

C#的一个重要设计目标是尽可能简单地从C / C ++过渡到它。 对字符串文字使用点语法对于只有C / C ++背景的人来说看起来奇怪,并且格式化字符串是开发人员在第一天使用该语言可能会做的事情。 所以我相信他们让它更接近熟悉的领域。

===============>>#17 票数:1

我认为它是静态的没有错。

静态方法的语义似乎对我来说更有意义。 也许是因为它是原始的。 在经常使用基元的情况下,你想让实用程序代码尽可能地使用它们。另外,我认为使用String.Format而不是“MyString BLAH BLAH {0}”语义要好得多。格式 。 ..

===============>>#18 票数:1

我还没有尝试过,但你可以为你想要的东西做一个扩展方法。 我不会这样做,但我认为它会起作用。

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

如果您想要非静态格式,云也可以使用StringBuilder StringBuilder.AppendFormat()

===============>>#19 票数:1

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

可能他们这样做是为了保持两个字符串彼此靠近,即

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

代替

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

您想知道索引映射到的内容; 也许他们认为“.Format”部分只会在中间添加噪音。

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

===============>>#20 票数:0

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

===============>>#21 票数:-1

String.Format至少获取一个String并返回不同的String。 它不需要修改格式字符串以返回另一个字符串,因此这样做没有意义(忽略它的格式)。 另一方面,使String.Format成为成员函数并不是一个很大的延伸,除了我不认为C#允许像C ++这样的const成员函数。 [如果确实如此,请纠正我和这篇文章。]

===============>>#22 票数:-2

.NET字符串是不可变的

因此,使用实例方法绝对没有意义。

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.

  ask by Jakub Šturc translate from so

未解决问题?本站智能推荐: