2012-01-07 89 views
7

可能重複:
Difference between Property and Field in C#C#領域與財產

我認爲基本屬性({ get; set; }),其中相同的公共領域,具有能夠唯一優勢改變而不會破壞二進制兼容性。回答我在這裏得到https://stackoverflow.com/a/8735303/331785,我發現這裏還有一個屬性的缺點。如果它們屬於值類型,則不能通過引用進行訪問。爲什麼會這樣,還有其他什麼區別?

+0

這裏你有答案:http://stackoverflow.com/questions/653536/difference-between-property-and-field-in-c-sharp – 2012-01-07 21:18:00

+5

這是一個謬誤。屬性不能通過引用,句號訪問。您將引用傳遞與引用類型混淆的常見錯誤。 – Noldorin 2012-01-07 21:18:59

+1

也就是說,默認情況下,引用類型的引用是按值傳遞的。按引用傳遞總是通過'ref'或'out'關鍵字完成的,對於引用類型和值類型都是如此。 – diggingforfire 2012-01-07 21:28:48

回答

14

我發現這裏還有一個屬性的缺點。如果它們屬於值類型,則不能通過引用進行訪問。爲什麼是這樣的

因爲在封面下,屬性只是一種方法。如果你看看IL,你會看到像get_PropertyNameset_PropertyName這樣的方法。問題是爲了支持使用引用,你需要能夠返回一個方法的引用。

public ref T MyProperty 
{ 
    get 
    { 
     return ref _underlyingField; 
    } 
} 

這當然是something entirely possible in the CLR;但沒有被C#語言暴露。

雖然這是可能的,CLR需要一些調整,以保持它的可驗證。該屬性的語法將不得不支持它。

但是,是任何有用的?正如你所說,一個領域可以做到這一點。如果你需要它;使用一個字段。支持它需要很多工作。在適當的情況下可能有很少的情況;並且會創造很多情況下,首先使用一個字段可能會更好。

4

屬性只是getX()setX()方法的糖衣語法。它看起來像一個領域,但它只是兩種方法。添加自動屬性的原因是爲了避免重複創建字段併爲該屬性創建一個標準的getter和setter,並且允許更改實現而不更改接口更簡單。

如果它們是一個值類型,它們不能被引用訪問的原因是值類型通常在堆棧上,因爲你只是調用一個方法。屬性中的getter必須被調用,返回的值必須在堆棧中被引用之前被壓入棧中。

+6

-1傳播價值類型的神話在堆棧上(即使與「一般」)。如果屬性(或字段)是一個類,它*不會*在堆棧上。 – 2012-01-07 21:23:56

+0

@JonSkeet我認爲他在談論getter的返回值,它將首先在一個寄存器中結束,然後可能在堆棧中,這樣就會得到一個可以被引用的地址。 – CodesInChaos 2012-01-07 21:27:46