2010-07-28 54 views
3

爲SO編寫另一個問題,我得到了一個我經常使用的模式,但我從未真正反映過。但現在,我不能確定這是否是正確的方式:返回IEnumerable <T>是否是一個很好的習慣實現INotifyCollectionChanged的集合

如果我有我的WPF控件將綁定到的集合,我幾乎總是返回IEnumerable<SomeType>。然而在內部,這在大多數情況下是ReadOnlyObservableCollection<SomeType>。我從來沒有遇到過這個問題,並且所有消費控件都會正確更新,因爲它們會檢查INotifyCollectionChanged-界面,所以不會令人驚訝。

但我現在的問題是,如果這是不好的做法,在簽名中只聲明IEnumerable<SomeType>而不是返回(也取決於)更強大的東西(INotifyCollectionChanged)。

更新:

我試圖澄清:

我的主要目的是返回一個IEnumerable<SomeType>。但大多數時候,返回的IEnumerable<SomeType>也執行INotifyCollectionChangedReadOnlyObservableCollection<SomeType>呢。消費控制相應地綁定(我的第二個意圖是什麼)。

也許我應該問:是否有一個接口完全包含IEnumerable和INotifyPropertyChanged。

+0

我不知道你在說什麼。一些示例代碼來顯示您所指的模式會很有幫助。 – 2010-07-28 20:08:40

+0

我很好理解這個問題。我經常對List <>做同樣的事情。 – Marcel 2010-07-28 20:18:18

+0

很晚了,但我已經這麼做了很多年,但今天遇到了一個破壞它的案例: - 我有一個屬性聲明爲IEnumerable ,由ObservableCollection 支持。 奇怪的是,綁定控件(數據網格)未能注意何時將項目添加到集合中,因此可能沒有收到通知。 – 2015-06-25 16:00:07

回答

4

請記住,IEnumerable<T>INotifyCollectionChanged都是接口 - 它們不是一個明確的類型。你可以設計你的具體類來實現兩個,沒有問題。您的API可以爲方法調用返回適當的接口。事實上,這是一個很好的設計 - 不是要避免的。

ObservableCollection<T>這樣做(間接通過Collection<T>),還實現了IList<T>以及其他接口。

如果您正在製作自己的自定義集合,並計劃使用數據綁定使用它,我會讓它實現IEnumerable<T>(或潛在IList<T>,如果合適的話)和INotifyCollectionChanged。這將爲代碼提供最佳的可用性,而且可以提高綁定的效率。


(和還依賴於)

然而,根據在接口上存在不屬於API的一部分是不好的做法。這是很危險的,並且返回一個接口而不是一個具體類型的原因之一就是允許實現稍後改變。通過依賴未聲明的接口,可以使代碼變得脆弱。

這就是說,我經常做你正在嘗試的,但它不是一個「硬」的依賴。相反,我使用IEnumerable<T>檢查INotifyCollectionChanged - 利用它,如果它實施。但是,如果「輔助」接口不存在,我確實允許代碼工作。

2

返回一個最小的接口而不是一個更豐富的接口通常是一個好主意。如果你有一個豐富的界面,那麼有更多的東西需要測試,而更多的東西可能會出錯。這也意味着如果您想避免發生重大變化,您必須始終在可預見的未來支持所有這些額外功能。這使得以後修改實現變得更加困難。

然而,取決於接口不保證的事情是一種不好的做法。如果有一天你沒有得到一個ObservableCollection但是其他類型的集合,那麼代碼將在運行時而不是在編譯時失敗。

2

我會傾向於認爲,如果只INotifyCollectionChanged是正確的,你不想只返回一個IEnumerable這將是非常想回國Object,你真正想要的是MemoryStream.當然,你可以轉換回類型你需要,但如果稍後有人來了,看到的是IEnumerable的返回類型,並寫入與返回值相匹配的代碼,但不會執行INotifyCollectionChanged

1

忘掉WPF的數據綁定,然後決定什麼是最好的返回,IEnumerable<T>或更多concrette類型。由於WPF使用反射來確定如何綁定到指定集合的​​最佳方式,因此您不必擔心。

+0

+1好點。但主要的場景是WPF-VMs(它不在我的BOs中),因此我認爲我不應該忘記。但在我的文章的第一個版本中,我沒有提到這一點,如果WPF只是許多場景中的一個,或者如果它在BO中,我發現你的答案非常好。 – HCL 2010-07-28 20:57:14

0

,如果這是不好的做法在簽名聲明只有IEnumerable<SomeType>,但返回(也取決於)一些更強大(INotifyCollectionChanged

返回值類型選擇,使讓消費者在不使用不安全的類型轉換的情況下處理值。

  1. 如果返回IEnumerable那麼價值消費者不應該做假設它是否是一個集合,或者是可以改變的集合或者它是一個可以改變,可以通知有關它的變化的集合。

使用IEnumerable的唯一方法就是枚舉它!沒有辦法確定有什麼變化,應該再次列舉!

  1. 如果返回ReadOnlyObservableCollection,則值使用者可以自由地假定它是一個集合,並且它可以通知它的更改。

ReadOnlyObservableCollection值消費者可以枚舉集合或可以訂閱更改通知,並在收到通知後再次枚舉集合。

IEnumerable接口下返回一些複雜集合是一個好習慣。

這是不好的做法,使用IEnumerableINotifyPropertyChanged轉換IEnumerableINotifyPropertyChanged或更復雜的東西。

有恰好包含IEnumerableINotifyPropertyChanged

接口遺憾的是沒有這樣的接口,只有ReadOnlyObservableCollection類。

相關問題