2013-12-12 5 views
6

私は奇妙な質問のように聞こえるかもしれないことを知っていますが、これはしばらくの間私の心の中で起こっています。System.String C#の型

私は、C#のSystem.String型が、実際には文字配列パラメータを持つコンストラクタを持つクラスであることを知っています。たとえば、次のコードは合法で、エラーが発生しません:

System.String s = new System.String("Hello".toCharArray()); 

私の質問は、何がすることは、単純にこのような文字の配列を受け入れるようにSystem.Stringクラスのために可能であるということである。

System.String s = "Hello"; 
+3

コンパイラチームはそれを可能にした。ここで

を使用すると、文字列型を理解するのに役立つかもしれないいくつかのことです。他のリテラルのように、 'Nullable '、拡張メソッドなど –

+0

それはインデクサーのために使用できますか?もしそうなら、それはどうしますか? – Transcendent

+0

これは 'if'文や' var'キーワードと同じように、言語構造です。単純に言語がどのように動作するのか、 'string'は使いやすい特殊なケースです。 –

答えて

8

お電話:

System.String s = new System.String("Hello".toCharArray()); 

をあなたが書くときあなたが明示的にコンストラクタ

を呼び出している:

string foo = "bar"; 

アンIL命令(Ldstr)は、その文字列への新しいオブジェクト参照をプッシュリテラル。コンストラクタを呼び出すのと同じではありません。

+1

くそ、Servyは魔法の力を持っています – Habib

3

これは、C# languageが文字列リテラルが可能であることを指定しているため可能です(§2.4.4.5文字列リテラルを参照)。 C#コンパイラとCIL/CLRは、これらのリテラルがどのように使用されているかをよくサポートしています。オペコードはldstrです。

独自のカスタムタイプにこのようなリテラルを含めることはサポートされていません。

-2

文字列は、特殊なclr型のようなものです。それらは唯一の不変参照型です。

var a = "Hello"; 
var b = new String("Hello".ToCharArray()); 
var c = String.Intern(b); // 'interns' the string... 
var equalsString = a == b; // true 
var equalsObj = (object)a == (object)b; // false 
var equalsInterned = (object)a == (object)c; // true !! 

a[0] = 't'; // not valid, because a string is immutable. Instead, do it this way: 
var array = b.ToArray(); 
array[0] = 't'; 
a = new String(array); // a is now "tello" 
+0

'彼らは唯一の不変参照型です。本当に?申し訳ありませんが、ありません。不変の参照型の*ロット*があります。これはもう一つです: 'public class Foo {}' – Servy

+0

@Servyこれは設計上の不変性です...文字列は不変です。 – Olivier

+1

まず、実際の違いはありません。次に、文字列は不変ではなく、技術的にはパブリックAPIで不変です。内部的に文字列は実際には突然変異している可能性がありますが、実際には突然変異しているため、不変性は実行時に強制されません。明らかにそれはそれを可能にする。 – Servy

関連する問題