2009-07-13 160 views
11

如果我有以下代碼:私人-setter屬性

public class MyClass 
{ 
    public string myName { get; private set; } 
    public string myId { get; set; } 
} 

私人編譯器生成的變量的設定器創建的。我希望setter不能僅用於對象初始化。但是,我如何才能最初設置myName變量?

閱讀有關對象的初始化我發現:

...它是隻讀的,代表 底層存儲的 私人領域具有我們 不能在使用 編譯器生成的名稱構造函數將它分配給 。該解決方案是使用[...]對象 初始化

的解決辦法是,那麼,使用方法:

MyClass mc = new MyClass { 
myName = "What ever", 
myId = "1234" 
}; 

但這在說結束了在編譯器錯誤:

屬性或索引 「MyClass.MyClass.myName」 不能在此上下文中,因爲 set訪問是不可訪問

那麼,有沒有一種方法可以實現使用對象初始化設置此值?如果有,那麼做什麼是正確的方法?

回答

6

私訂意味着你只能從東西是一個初始化(套)它MyClass的成員。例如:

 public class MyClass { 
     public string myName { get; private set; } 
     public string myId { get; set; } 

     public static MyClass GetSampleObject() { 
      MyClass mc = new MyClass 
      { 
       myName = "Whatever", 
       myId = "1234" 
      }; 
      return mc; 
     } 
    } 

(我複製並粘貼您的初始化代碼到GetSampleObject方法)。

但是,如果您嘗試將其設置在MyClass之外,則會出現編譯器錯誤,因爲private是私有的。

12

不,沒有辦法做到這一點。對象初始化程序只允許您訪問在初始化程序之外可訪問的字段和屬性。

你最好的選擇是使用一個明確設置這些屬性的構造函數。

+0

謝謝,我想告訴學生,如果使用3.0的新功能可以實現這一點,但看起來答案是否定的。現在我必須爲這本書提交勘誤表:P – jluna 2009-07-13 21:54:12

5

如果他們需要在初始化進行設置,然後考慮將它們作爲參數傳遞給構造

+1

是的,爲什麼簡單的事情變得複雜? – 2009-07-13 20:33:59

+0

因爲如果你想在對象初始化的時候做一些事情,你可以在構造函數中做。在其他任何地方做它都沒有意義。 – 2009-07-13 20:48:17

1

我已經INT過去的這個要求,以及對OR/M的東西。我基本上做的是使用一個真正的財產與支持者領域,並檢查,看看是否已經設置屬性。如果是這樣,拋出一個異常。

public string myName 
{ 
    get{ return _myName; } 
    set 
    { 
     if(_myName != null && _myName != value) 
      throw new Exception("The myName property may only be set once."); 
     _myName = value; 
    } 
} 

private string _myName; 

而另一種選擇OR/M的兼容性還需要構造函數初始化的優勢:對MYNAME

public class MyClass 
{ 
    [Obsolete("For ORM use only!")] 
    [EditorBrowsableState(EditorBrowsableState.Never)] 
    public MyClass(){} 

    public MyClass(string name){ myName = name; } 

    public string myName { get; private set; } 
    public string myId { get; set; } 
}