2012-10-09 112 views
11

爲什麼在C#中我的兩個變量指向不同的DateTime對象?C#DateTime總是創建新的對象?

DateTime a1 = DateTime.Now; 
DateTime a2 = a1; 

a1 = a1 + TimeSpan.FromMinutes(15); 
a2 = a2 - TimeSpan.FromMinutes(16); 

意識到,其實a2爲指向一個新的對象,它是從A1不同。

但在其他情況下。假設我有一個班級人員,年齡= 1;

Person a1 = new Person(); 
a2 = a1; 
a2 = Person.Age = 2; 

在Person Case中,a1和a2指向同一個對象。我真的很困惑,任何人都可以解釋?

+2

的DateTime是值類型,而不是一個 –

+1

引用類型檢查這個答案 http://stackoverflow.com/a/4265417/1511796 –

回答

23

DateTime是一個值類型 - 結構。

對於值類型,當你做這樣的事情:

DateTime a2 = a1; 

a2得到的a1值的副本。它與相同的內存位置不是相同的引用,而是完整的單獨副本。

另一方面,Person是一個參考類型 - 一類。

當你這樣做:

Person p2 = p1; 

與參考類型,參考的是p2點是相同的一個p1點。所以一個變化是兩個變化。

請參閱MSDN上的Value Types and Reference Types

+0

日期時間是不變的,如果我沒說錯。我其實很困惑。不可變的字符串,但那是參考類型。我想問的是,對於不可變性而言,實際上哪種類型是不起作用的?我會感謝您的答覆,謝謝。 –

+1

@NomiAli - 爲什麼不發表問題呢?值類型通常被創建爲不可變(並且它非常適合它們的語義)。 'string'由於許多不同的原因被創建爲不可變(優化爲一)。您可以創建不可變的值或引用類型。 – Oded

3

這裏的區別是DateTime是一個值類型,我假設Person是一個引用類型(class)。

對於值類型的變量賦值,實際上是將內存的內容從一個位置複製到另一個位置。

但是,在引用類型的情況下,您仍然指向同一塊內存。

3

這裏有兩個獨立的概念。第一個是DateTime是一個值類型(a.k.a.一個結構),而Person是[推測]一個引用類型(一個類)。正因爲如此,當你做:

DateTime date1 = DateTime.Now; 
DateTime date2 = date1; 

date2會導致複製的價值,所以這兩個變量將不會引用同一個對象。

帶班,當你這樣做:

Person p1 = new Person(); 
Person p2 = p1; 

p1實際上並不包含Person,它只是包含引用一個人。然後將該參考值(按值)複製到p2。複製該引用的效果是兩個變量現在都「指向」或「引用」同一個對象。

接下來是可變性問題。在這種情況下,Person是可變類型。這意味着它可以改變。另一方面,不可修改的類型一旦構建就不能改變。

線:

p2.Age = 2; 

實際上正在改變p2引用,而且由於p2p1都引用相同的對象的對象,p1.Age2該行代碼後。

現在,爲了演示,讓我們做一個不變Person類:

public class Person 
{ 
    private int _age; 
    public Person(int someAge) 
    { 
     _age = someAge; 
    } 

    public int Age 
    { 
     get { return _age; } 
    } 

    public Person Grow() 
    { 
     return new Person(_age + 1); 
    } 
} 

如果我們做這樣的事情:

Person p1 = new Person(1); 
Person p2 = p1; 
p2 = p2.Grow(); 

第二行只是在做它之前,確保這兩個指向同一個對象,但第三行是不同的。我們的Grow方法返回一個新的Person對象,而不是改變(或變異)該對象使其成長一歲。這樣做後p2p1將不再引用相同的對象;我剛剛更改了方法創建的新對象p2的引用。

第二個例子與DateTime的情況很相似。你不能改變DateTime對象;它是不可改變的。調用它的方法(在這種情況下,加號和減號運算符)返回並且全新的對象。按照慣例,如果沒有一些令人信服的理由,值類型不應該是可變的,因爲處理它們往往是棘手的。引用類型可以是不可變的或可變的;沒有重大問題(在一般情況下)。

4

正如其他人已經指出DateTime是一個結構,而不是一個類,因此是一個值類型。如果您更改用於顯示結構的文本顏色,您可以在Visual Studio編輯器中看到它。在菜單Tools>Options打開對話框,並定位到Environment>Fonts and Colors

enter image description here

它有利於改變的代表,枚舉,接口和結構(值類型)的顏色。