2010-09-30 51 views
1

字符串是不可變的參考類型如何?證明給我看 ?字符串是參考類型

+3

需要證明什麼?沒有實例方法修改實例,因此該類型是不可變的。 – 2010-09-30 04:50:16

+0

這可能是http://stackoverflow.com/questions/2365272/why-net-string-is-immutable或http://stackoverflow.com/questions/93091/why-cant-strings-be-mutable -in-java-and-net – 2010-09-30 04:51:16

+6

否則證明。我認爲舉證責任在你身上,因爲我們沒有提出嘲笑。我們將繼續使用它,好像它是可變的,直到另外顯示:-) – paxdiablo 2010-09-30 04:53:20

回答

1

簡化證明是簡單地通過每一個可從外部訪問(publicprotectedinternalprotected internal)構件前去見如果能發生變異的對象的問題。它們都不能,因此它是不可變的。

的如何很容易:

不變性的引用類型執行部件定義:

public class TestClass 
{ 
    private readonly int _someValue; 
    public TestClass(int val){_someValue = val;} 
    public int Value{get{return _someValue;}} 
} 

不變性通過單獨接口強制執行:

public class TestClass 
{ 
    private int _someValue; 
    public TestClass(int val){_someValue = val;} 
    public int Value{get{return _someValue;}} 
} 

這兩個類定義不可改變引用類型。第一個是內部和外部不可變第二個是內部可變的,但外部不可變,因爲沒有外部可訪問的方法可以更改任何實例成員的值。

字符串在第二種情況下偶然,雖然這是一個實現細節。

0
Why string is immutable and StringBuilder is mutable ? 

字符串生成器是可變的.IE是下面的示例中的「富」作爲參考類型傳遞。所以輸出helloanish純參考type.The : 例如:

class Program 
{ 
static void Main(string[] args) 
{ 
StringBuilder y =new StringBuilder(); 
y.Append("hello"); 

Program p = new Program(); 
p.foo(y); 
Console.WriteLine(y); 
} 

void foo(StringBuilder sb) 
{ 
sb .Append("anish:"); 
} 
} 

Stirng是不可變的。在某些方面,它是數值類型。這些是公知的爲不可改變。以下示例將「foo」被傳遞是一個字符串,但此充當值類型。所以輸出是'你好'

E.g:

class Program 
{ 
static void Main(string[] args) 
{ 
string y =string.Empty; 
y="hello"; 

Program p = new Program(); 
p.foo(y); 
Console.WriteLine(y); 
} 

void foo(string sb) 
{ 
sb +="anish:"; 
} 
} 

注意:注意其他類型也只是串。有的。

不是爲函數成員聲明創建一個新的存儲位置,可以在ref類型的幫助下使用相同的存儲位置。

E.g:

class Program 
{ 
static void Main(string[] args) 
{ 
string y =""; 
y="hello"; 

Program p = new Program(); 
p.foo(ref y); 
Console.WriteLine(y); 
} 

void foo(ref string sb) 
{ 
sb="anish:"; 
} 
} 

輸出不你好,其阿尼什

缺貨類型:同一個參考.The的事情是,最初的變量是未分配的。

對我的博客看看:HTTP:http://anishmarokey.blogspot.com/2009/08/mutable-vs-immutable.html

0

字符串在C#中的引用類型。當我們創建字符串類型的變量時,在內存中創建一個字符串類型的對象。該對象一旦創建就無法修改。

如果我們爲相同的字符串變量賦值其他值,則會在內存中創建新對象,並且字符串變量指向該對象的新地址。

這就是爲什麼字符串被視爲不可變類型的原因。

正如Ruel所說,您可以獲得更多關於字符串類型here的信息。

+0

這不是一個證明,是嗎? – 2010-09-30 06:11:04

6

您可以隨時檢查ECMA C# Language Specification:

8.2.1預定義類型
C#提供了一組預定義的類型,其中大部分將是熟悉 C和C++開發人員。 預定義的參考類型是對象 和字符串。類型對象是所有其他類型的最終基本類型 。 類型字符串用於表示 Unicode字符串值。 字符串的值是不可變的

+1

+1 RTFS - 閱讀神奇規格! :-) – 2010-09-30 05:08:48

+0

這並不回答「如何」,也沒有證明規範確實遵循。 – 2010-09-30 12:59:48

2

證明該字符串(如果你的意思是System.String當然)是引用類型是很容易的。

所有值類型都應該從ValueType繼承(隱式地是caurse),但是System.String直接從System.Object繼承,所以使用消除方法的字符串不能是任何其他引用類型。

Console.WriteLine("".GetType().BaseType); //prints System.Object 
Console.WriteLine(1.GetType().BaseType); //prints System.ValueType 

要檢查不變性,您應該在System.String類中找到任何「變異」方法。我找不到任何東西!因爲所有的「變異」的方法實際上返回另一個實例,你可以很容易地通過調用object.ReferenceEquals檢查:

Console.WriteLine(object.ReferenceEquals(s, s + "1")); //False 
Console.WriteLine(object.ReferenceEquals(s, s.Insert(0, "12"))); //False 

您還可以檢查其他的方法,你會看到,所有他們都具有相同的行爲:他們返回新的對象,但它們不會改變現有的值。

class System.String文檔:

不變性和StringBuilder的 類

String對象被稱爲不可變 (只讀),因爲它已經被後其值不能 被修改創建。 似乎修改字符串 對象的方法實際上會返回包含修改的新字符串 對象。