2016-08-12 30 views
3

我不知道爲什麼在C#中不允許使用僅{組}財產自動生成屬性類類型,如:爲什麼屬性只能包含C#中的接口類型的setter?

class Person { 
    public string Name { set; } // Compile-time error 
} 

但是,它允許在接口類型:

interface IPerson { 
    string Name {set;} //Allowed 
} 

我讀過類似的問題here,這是非常罕見的做法 - 我的理解,但我想知道爲什麼CLR甚至允許這樣做?

+2

更重要的問題(我相信Eric Lippert會希望你問的)是,爲什麼不應該編譯器允許你這樣做?你有義務提出強烈的反對意見,而不是要求支持它。在某些情況下,我希望通過接口強制執行單向數據流是非常合理的。 –

+0

該財產的合法實施是它無能爲力。將價值存儲到財產將被忽略。爲什麼編譯器應該支持什麼是有效的死代碼? –

回答

8

有一個簡單的原因。如果您使用自動實施的屬性(隱藏專用字段生成)。那麼爲什麼你需要設置一個你永遠不會獲得(隨後使用)的價值。

對於接口,您沒有使用自動實現的屬性,它只是一個約定,指定實現類應該具有名爲Name的字符串屬性,該屬性應實現Setter方法。所以,你可以這樣做:

interface IPerson 
{ 
    string Name { set; } 
} 

class Person : IPerson 
{ 
    private string _name; 
    public String Name 
    { 
     set { _name = value; } 
    } 
} 

所以在最後,C#編譯器試圖阻止我們做的事情沒有任何意義是:提供一個私人隱藏字段的自動設置方法那永遠不會得到。

2

因爲什麼是一個屬性的點,你可以指定一個值,但無法觀察它?

以下是完全合法的

class Person { 
    private string _name; 
    public string Name { set { _name = value } } 
} 

原因自動屬性不會讓你這麼做是因爲你永遠無法得到的數值超出它被寫後,你所擁有的手動實現的屬性將該值設置爲其他字段的機會。

接口允許的原因是接口可以使用public string Name {private get; set;}來描述手動執行的版本或自動執行的版本。

2

您正在使用類中的自動屬性,該屬性定義爲使用getter可訪問的隱藏私人字段。

如果你只是使用普通的屬性,你可以絕對只有一個setter:

public string Name { 
     set { 
      Console.WriteLine("hi"); 
     } 
    } 
2
class Person { 
    public string Name { set; } // Compile-time error 
} 

支持字段是人跡罕至,所以沒有辦法得到它。在C#規範中解釋說,由於沒有另一個沒有意義,所以它是不允許的。

由於後臺字段不可訪問,因此只能通過屬性訪問器讀寫 ,即使在包含類型中也是如此。 這意味着自動實現的只讀或只寫 屬性沒有意義且不被允許。然而,不同地設置每個訪問器的訪問級別是可能的。

編譯器小組發出一個調用,認爲不允許它會更好,因爲沒有意義,通過允許它,開發人員可以編寫更多容易出錯的代碼。

他們在語言的其他方面也做出同樣的判斷,比如不允許大部分時間都在案例陳述中出現。 (你可以通過一個沒有代碼的案例)。從技術上講,在這種情況下,你可以說它提供了好處,但他們認爲好處並未超過潛在的錯誤成本。

1

該接口僅用於確保您的課程正在實施該方法。然而,當你創建一個班級時,沒有任何一個你永遠無法擁有的財產

相關問題