2010-01-13 32 views
2

當創建一個映射,我讀您的收藏屬性應該是這樣的:這是什麼樣的屬性?有必要嗎?

public virtual ReadOnlyCollection<Product> Products 
    { 
      get { return new ReadOnlyCollection<Product>(new List<Product>(_products).AsReadOnly()); } 
    } 

爲什麼一定要這樣?它每次被引用時似乎都會返回一個新的集合?

回答

7

它返回一個包裝類實例,它阻止調用者能夠直接修改您要返回的集合。

如果你簡單地返回底層列表,任何調用者將能夠改變它可能破壞實際上擁有列表中的類方法。

即使您將列表作爲只讀接口(例如IEnumerable或ICollection)返回,也不會阻止調用方執行運行時轉換並獲取列表。

通過返回一個包裝對象,可以防止調用者有史以來能夠改變列表。包裝不會公開任何允許更改底層列表的方法,並且試圖轉換包裝器對象將失敗。包裝器不復制數據 - 它只是保持對列表的引用,並防止寫入操作。

對於ORM映射,這允許對象模型控制在哪個訪問點可以更改對象之間的關係。

+0

所以它基本上確保你不會嘗試和改變映射的這個'結束'列表,你必須改變它在你已經設置cascade = update/save/etc.和inverse =假? – mrblah 2010-01-13 15:03:37

+1

是的。這是一種控制訪問點的方法,通過它可以更改集合。 – LBushkin 2010-01-13 15:04:56

1

我相信它建議像這樣構建它,所以你不能修改調用代碼中的列表。通常你可以操作它(因爲它會通過引用傳遞) - 添加項目,刪除項目等。這確保你必須使用setter來更改內部列表。

我不會說它就像那樣,除非你想讓你的getters返回只讀列表。

0

它具體返回一個無法修改的新集合。似乎有點愚蠢,但。除非我記錯了,則可能是:

public virtual ReadOnlyCollection<Product> Products 
{ 
    get 
    { 
     return new List<Product>(_products).AsReadOnly(); 
    } 
} 

,或者,如果_products是某種List<Product>已經:

public virtual ReadOnlyCollection<Product> Products 
{ 
    get 
    { 
     return _products.AsReadOnly(); 
    } 
} 
0

此代碼似乎是多餘的,我...爲什麼不return _products.AsReadOnly()? (假設_products是一個List<T>,陣列或任何暴露了AsReadOnly方法的類型)

4

您的代碼看起來有點奇怪。首先它創建一個_products的副本,然後使其只讀,然後將其重新包裝在ReadOnlyCollection中!

如果要公開應該是隻讀的,做這樣的事情的集合:

private List<Product> _products = new List<Product>(); 

private ReadOnlyCollection<Product> _readonlyProducts = 
    new ReadOnlyCollection(_products); 

public ReadOnlyCollection<Product> Products 
{ 
    get 
    { 
     return _readonlyProducts; 
    } 
} 

無需每次重新創建ReadOnlyCollection(或複製或或雙卷集)。

2

您的收藏不包含已將設爲永遠只讀。這取決於列表的具體內容。如果它實際上只是一個引用列表,那麼除非您明確需要只讀集合,否則您甚至可以返回IEnumerable而不是ReadOnlyCollection

要使它成爲一個只讀集合,我會做:

private List<Product> products = new List<Product>(); 

public ReadOnlyCollection<Product> Products { get { return products.AsReadOnly(); } } 

沒有必要用new ReadOnlyCollection語句來包裹AsReadOnly方法。或者你可以這樣做:

public ReadOnlyCollection<Product> Products { get { return new ReadOnlyCollection<Product>(products); } } 

不過,我只是呼籲AsReadOnly去,因爲我想在內部它只是無論如何包裝列表爲你。

0

我想_productsICollection<Product>IEnumerable<Product> - 在這種情況下,我認爲這是足夠有new List<Product>(_products).AsReadOnly()。 如果_products是​​那麼new ReadOnlyCollection<Product>(_products)就足夠了。 是否使用這個決定取決於類的設計 - 在某些情況下,將每個產品隱藏的收集適配器返回到只讀ProductView或ProductDTO實例甚至更好。