.net 为什么String.Format是静态的?

.net 为什么String.Format是静态的?,.net,string,.net,String,比较 与 为什么.Net设计人员选择静态方法而不是实例方法?你怎么看?我认为这是因为它是一种创建者方法(不确定是否有更好的名称)。它所做的一切就是获取您给它的内容并返回一个字符串对象。它不会对现有对象进行操作。如果它是非静态的,则需要以字符串开头。,因为Format方法与字符串的当前值无关。未使用字符串的值。它接受一个字符串并返回一个。我认为它是静态的没有什么错 静态方法的语义对我来说似乎更有意义。也许是因为它是原始的。在经常使用原语的地方,您希望使使用原语的实用程序代码尽可能轻。。另外,我认为

比较


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

我认为这是因为它是一种创建者方法(不确定是否有更好的名称)。它所做的一切就是获取您给它的内容并返回一个字符串对象。它不会对现有对象进行操作。如果它是非静态的,则需要以字符串开头。

,因为Format方法与字符串的当前值无关。未使用字符串的值。它接受一个字符串并返回一个。

我认为它是静态的没有什么错


静态方法的语义对我来说似乎更有意义。也许是因为它是原始的。在经常使用原语的地方,您希望使使用原语的实用程序代码尽可能轻。。另外,我认为使用String.Format比“MyString BLAH BLAH{0}”的语义要好得多。Format…

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


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

我还没有尝试过,但是你可以根据自己的需要制作一个扩展方法。我不会这么做,但我认为这会奏效

我还发现
String.Format()
与其他模式化静态方法(如
Int32.Parse()
long.TryParse()
)更为一致

如果需要非静态格式,也可以使用
StringBuilder

字符串。Format
至少接受一个字符串并返回另一个字符串。它不需要修改格式字符串来返回另一个字符串,因此这样做没有什么意义(忽略它的格式)。另一方面,将<代码>字符串String。格式< /C> >不是一个成员函数,除了我不认为C++允许C++成员的const成员函数。[如果有,请纠正我和这篇文章。]

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

另一方面,string类的所有函数都不会作用于字符串,而是返回一个新的string对象,因为字符串是不可变的


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

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

如果它是非静态的,那么首先需要一个字符串

它是:格式字符串


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

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

我想您必须对它非常挑剔,但正如人们所说的,由于隐含的语义,String.Format是静态的更有意义。考虑:

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

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

拥抱并延伸。:)


请参阅:

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

"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.
所以我现在可以从

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

这是我当时比较喜欢的。 如今(2014年),我不再费心了,因为不断地将其重新添加到我创建的每个随机项目中,或者链接到某个utils库中,这只是另一个麻烦

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

  • 复制Java
  • 当时写这本书的人主观上更喜欢它

我真的找不到任何其他有效的理由。NET字符串是不可变的

因此,拥有一个实例方法是毫无意义的

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

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

他们这样做可能是为了让两个字符串在词汇上彼此靠近,即

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("Foo {0}", "Bar");
您想知道索引映射到什么;也许他们认为“.Frand”部分只是在中间增加了噪声。 有趣的是,ToString方法(至少对于数字)正好相反:number.ToString(“000”),格式字符串位于右侧

.NET字符串是不可变的
因此,拥有一个实例方法是毫无意义的

"Hello {0}".F(Name);
按照这种逻辑,string类不应该有返回对象修改副本的实例方法,但它有很多(Trim、ToUpper等)。此外,框架中的许多其他对象也这样做

我同意,如果他们将其作为实例方法,
Format
似乎是个坏名字,但这并不意味着功能不应该是实例方法

为什么不是这个?这和我的想法是一致的

@贾里德:


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

不,他们不是

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

那是你的错误。词
String.Format("Foo {0}", "Bar");
"Foo {0}".Format("bar");
"Hello {0}".ToString("Orion");
"{0}".Format(12);
new String("{0}").Format(12);
CString csTemp = "";
csTemp.Format("Some string: %s", szFoo);
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");
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);
    }
}