39

比較

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

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

.Net 設計者がインスタンス メソッドではなく静的メソッドを選択したのはなぜですか? どう思いますか?

4

22 に答える 22

49

Format メソッドは文字列の現在の値とは関係がないためです。

.NET 文字列は不変であるため、これはすべての文字列メソッドに当てはまります。

静的でない場合は、最初に文字列が必要になります。

フォーマット文字列。

これは、.NET プラットフォームの多くの設計上の欠陥の 1 つの例にすぎないと思います (これは炎上しているわけではありません。.NET フレームワークは、他のほとんどのフレームワークよりも優れていると思います)。

于 2008-08-22T19:22:33.320 に答える
29

実際には答えはわかりませんが、文字列リテラルでメソッドを直接呼び出すという側面と関係があると思われます。

私の記憶が正しければ (私は古い IDE を手元に持っていないため、実際には検証しませんでした)、C# IDE の初期のバージョンでは、IntelliSense で文字列リテラルに対するメソッド呼び出しを検出するのに問題があり、発見しやすさに大きな影響を与えました。 APIの。その場合、次のように入力しても何の助けにもなりません。

"{0}".Format(12);

入力を強制された場合

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

Format メソッドを静的メソッドではなくインスタンス メソッドにするメリットがないことは明らかです。

.NET ライブラリは、MFC を提供したのと同じ多くの人々によって設計されました。特に String クラスは、MFC の CString クラスに非常によく似ています。MFC にはインスタンスの Format メソッド (.NET の中かっこスタイルではなく、printf スタイルの書式設定コードを使用する) がありますが、CString リテラルのようなものがないため、これは面倒です。したがって、私が取り組んだ MFC コードベースには、次のようなものがたくさんあります。

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

これは痛いです。(上記のコードが MFC でも優れた方法であると言っているわけではありませんが、プロジェクトのほとんどの開発者が CString::Format の使用方法を学んだ方法のようです)。その遺産から、API 設計者はそのような状況を再び回避しようとしていたことが想像できます。

于 2008-08-23T11:05:01.653 に答える
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.
于 2008-08-22T20:38:40.767 に答える
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 のコピー
  • 当時それを書いていた男は、主観的にそれをより気に入っていました。

私が見つけることができる他の正当な理由は実際にはありません

于 2008-08-23T04:27:03.323 に答える
6

Format は文字列自体ではなく、「フォーマット文字列」を取るためだと思います。ほとんどの文字列は、"Bob Smith" や "1010 Main St" などに相当し、"Hello {0}" には相当しません。通常、テンプレートを使用して別のテンプレートを作成する場合にのみ、これらの書式文字列を入力します。ファクトリ メソッドのような文字列であるため、静的メソッドに適しています。

于 2008-09-16T10:28:21.197 に答える
5

クリエーターメソッドだからだと思います(もっといい名前があるかどうかはわかりません)。与えられたものを受け取り、単一の文字列オブジェクトを返すだけです。既存のオブジェクトには作用しません。静的でない場合は、最初に文字列が必要になります。

于 2008-08-22T19:17:18.920 に答える
4

JAVAがこのようにしたので、.NET設計者がこのようにしたのかもしれません...

抱きしめて伸ばす。:)

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

于 2008-08-23T00:38:38.647 に答える
4

.NET 文字列は不変
であるため、インスタンス メソッドを使用してもまったく意味がありません。

そのロジックにより、文字列クラスには、オブジェクトの変更されたコピーを返すインスタンス メソッドが存在しないはずですが、十分に存在します(Trim、ToUpper など)。さらに、フレームワーク内の他の多くのオブジェクトもこれを行います。

彼らがそれをインスタンスメソッドにするとしたら、それは悪い名前のように思えることに同意しますが、Formatそれは機能がインスタンスメソッドであってはならないという意味ではありません.

なぜこれではないのですか?.NET フレームワークの残りの部分と 一貫性があります。

"Hello {0}".ToString("Orion");
于 2008-08-23T06:44:52.760 に答える
3

Format メソッドは文字列の現在の値とは関係がないためです。文字列の値は使用されません。文字列を受け取り、それを返します。

于 2008-08-22T19:17:26.530 に答える
2

A big design goal for C# was to make the transition from C/C++ to it as easy as possible. Using dot syntax on a string literal would look very strange to someone with only a C/C++ background, and formatting strings is something a developer will likely do on day one with the language. So I believe they made it static to make it closer to familiar territory.

于 2008-09-16T02:44:53.977 に答える
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);
于 2008-08-23T11:10:27.987 に答える
2

もう 1 つの理由String.Formatは、C からの機能との類似性ですprintf。これにより、C 開発者が言語を簡単に切り替えられるようになるはずでした。

于 2008-09-02T12:34:17.817 に答える
2

@ジャレッド:

インスタンスを最初の変数として受け取る、オーバーロードも継承もされていない静的メソッド (Class.b(a,c) など) は、メソッド呼び出し (ab(c) など) と意味的に同等です。

いいえ、そうではありません。

(それが同じ CIL にコンパイルされると仮定すると、そうあるべきです。)

それはあなたの間違いです。生成される CIL は異なります。違いは、値に対してメンバー メソッドを呼び出すことができないnullため、CIL が値に対してチェックを挿入するnullことです。これは明らかに静的バリアントでは行われません。

ただし、値許可String.Formatしないため、開発者は手動でチェックを挿入する必要がありました。この観点から、メンバーメソッドのバリアントは技術的に優れています。null

于 2008-08-23T08:25:19.257 に答える
2

インスタンス メソッドは、何らかの状態を維持するオブジェクトがある場合に適しています。文字列をフォーマットするプロセスは、操作している文字列に影響を与えず (読み取り: その状態を変更しません)、新しい文字列を作成します。

拡張メソッドを使用すると、ケーキを手に入れて食べることもできます (つまり、後者の構文が夜の睡眠を改善するのに役立つ場合は、後者の構文を使用できます)。

于 2008-08-22T19:19:32.330 に答える
2

一般的には String.Format を使用する方が見栄えが良いと思いますが、「フォーマット」したい変数に文字列が既に格納されている場合は、非静的関数が必要な点がわかりました。

余談ですが、文字列クラスのすべての関数は文字列に作用しませんが、文字列は不変であるため、新しい文字列オブジェクトを返します。

于 2008-08-22T19:22:32.103 に答える
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);
    }
}

それはずっと簡単に流れます、IMHO。

于 2008-08-25T22:15:14.160 に答える
1

静的であることには何の問題もありません..

静的メソッドのセマンティクスは、私にはもっと理にかなっているようです。プリミティブだからなのかな。プリミティブが頻繁に使用される場所では、それらを操作するためのユーティリティ コードをできるだけ軽量にしたいと考えてます。 ..

于 2008-08-22T19:19:10.443 に答える
1

まだ試していませんが、必要な拡張メソッドを作成できます。私はそれをしませんが、うまくいくと思います。

また、、 などString.Format()の他のパタ​​ーン化された静的メソッドと一致していることもわかりました。Int32.Parse()long.TryParse()

StringBuilder非静的フォーマットが必要な場合 は、クラウドも使用します。StringBuilder.AppendFormat()

于 2008-08-22T19:21:06.803 に答える
1

インスタンスを最初の変数として受け取る、オーバーロードされておらず、継承されていない静的メソッド (Class.b(a,c) など) は、メソッド呼び出し (ab(c) など) と意味的に同等であるため、プラットフォーム チームは任意の、審美的な選択。(それが同じ CIL にコンパイルされると仮定すると、そうあるべきです。) 知る唯一の方法は、理由を尋ねることです。

おそらく彼らは、2 つの文字列を辞書的に近づけるためにそれを行ったのでしょう。

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

それ以外の

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

インデックスが何にマップされているかを知りたい。おそらく彼らは、「.Format」部分が途中でノイズを追加するだけだと考えていました。

興味深いことに、ToString メソッド (少なくとも数値の場合) は反対です: number.ToString("000") の右側にフォーマット文字列があります。

于 2008-08-23T05:41:40.930 に答える
-1

文字列は不変であるため、String.Format は静的メソッドである必要があります。インスタンスメソッドにするということは、それを使用して既存の文字列の値を「フォーマット」または変更できることを意味します。これはできません。新しい文字列を返すインスタンス メソッドにするのは意味がありません。したがって、これは静的メソッドです。

于 2008-08-22T20:02:37.220 に答える
-1

String.Format少なくとも 1 つの文字列を取り、別の文字列を返します。別の文字列を返すためにフォーマット文字列を変更する必要はないため、それを行う意味はほとんどありません (フォーマットを無視します)。一方で、String.FormatC# では C++ のように const メンバー関数を使用できるとは思えないことを除けば、メンバー関数にするのはそれほど難しいことではありません。[もしそうなら、私とこの投稿を修正してください。]

于 2008-08-22T19:22:23.663 に答える
-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.
于 2008-08-23T05:20:58.437 に答える