C#类库集合ObservableCollection <T> vs Collection <T>

Ron*_*obs 8 .net c# silverlight wpf

我正在创建一个类库,可以在许多情况下使用ASP.NET,控制台应用程序,其他类库和XAML目标,如Silverlight或WPF.

最初我决定将集合公开为IList.但是当使用XAML编写样本时,我发现如果我想让它很容易绑定到这些集合,我需要使用ObservableCollection.

我有什么选择?

我可以让库暴露ObservableCollection并强制对与XAML无关的用户.那是一件坏事?

我可以使我的类通用,允许调用者指定他们想要的集合类型,只要它实现ICollection,也许默认为Collection

我可以创建一组使用ObservableCollection的类和一个不说Foo和ObservableFoo的类.

我可以在我的类中实现INotifyCollectionChanged但是当ObservableCollection为我做这件事时,这似乎很愚蠢.

显然我正在努力保持代码干净简单,但支持数据绑定似乎很重要.

有什么建议?

编辑:尝试使用两种替代方法创建可移植类库项目.

在Foo课我有

    private readonly Collection<string> strings = new Collection<string>();

    public ReadOnlyCollection<string> Strings
    {
        get
        {
            return new ReadOnlyCollection<string>(this.strings);
        }
    }
Run Code Online (Sandbox Code Playgroud)

在班级ObservableFoo我有

    private readonly ObservableCollection<string> strings = new ObservableCollection<string>();

    public ReadOnlyObservableCollection<string> Strings
    {
        get
        {
            return new ReadOnlyObservableCollection<string>(this.strings);
        }
    }
Run Code Online (Sandbox Code Playgroud)

非常简单的单元测试代码是

    [TestMethod]
    public void TestMethod1()
    {
        var foo = new ObservableFoo(); // or new Foo()

        Assert.AreNotEqual(0, foo.Id);
        Assert.AreNotEqual(0, foo.Strings.Count);
    }
Run Code Online (Sandbox Code Playgroud)

唯一的缺点是,当我使用ReadOnlyObservableCollection时,测试项目得到了这个编译错误

类型'System.Collections.ObjectModel.ReadOnlyObservableCollection`1'在未引用的程序集中定义.您必须添加对程序集'System.Windows,Version = 2.0.5.0,Culture = neutral,PublicKeyToken = 7cec85d7bea7798e,Retargetable = Yes'的引用

因此,在这种情况下,使用ReadOnlyObservableCollection将强制用户添加对System.Windows的引用,这是一个缺点.

编辑:我想出了一个我在博客上发布的解决方案 - 请参阅如何使库可移植并且数据绑定同时友好?

Vla*_*lad 3

这得看情况。如果您正在编写纯模型库,则公开 WPF 特定的接口是没有意义的;这将强制用户链接 WPF 库,即使他们不需要。即使不是,它也会暴露用户不需要的东西,恕我直言,这不是一个好的设计。

如果您的库不限于模型使用,我会将其分为几个部分:所有使用场景所需的核心、具有 WPF 特定接口的 WPF 依赖部分、可能具有 ASP 特定功能的 ASP 特定部分等等。用户将选择他们需要的部件并使用它们。


编辑:正如 @Julien 的评论所述,ObservableCollection<T>现在是核心的一部分,因此包含它不会使用户依赖于 WPF 特定的库。尽管如此,这个想法仍然是一样的。对于 WPF 使用,您通常需要提供/使用特定功能(ObservableCollectionINotifyPropertyChanged/ DependencyObject、依赖属性、仅 UI 线程中的通知等)。这意味着它们属于项目的一个单独的、特定于 WPF 的部分。

因此,您可以使该库由几个部分组成:Library.Core.dll 包含通用/模型开发所需的函数,Library.WPF.dll 处理 WPF 特定的内容并使用 Library.Core.dll,也许是 Library.Console.dll以及 Library.ASP.dll 。WPF的用户会使用Library.Core.dll和Library.WPF.dll,控制台程序可能需要Library.Core.dll和Library.Console.dll等等。