将通用集合公开为只读是否有良好的模式?

时间:2010-10-08 21:19:31

标签: c# wpf generics architecture design-patterns

所以我有这些类暴露了一组子对象。

我不希望其他类在集合中添加或删除对象,因为我需要连接到子对象中的事件,因此当它们被添加或删除时,我希望能够进行其他处理。但我真的很喜欢内部操纵泛型的简易性。

我是否提到这是一个WPF应用,所以我需要INotifySupport?

我能想出的最好的就是这样。

public class foo : INotifyPropertyChanged
{
    protected List<ChildFoo> _Children = new List<ChildFoo>();

    public foo()
    {
    }

    public void AddChild(ChildFoo newChild)
    {
        DoAttachLogic(newChild);
        _Children.Add(newChild);
        NotifyPropertyChange("Children");
    }

    public void RemoveChild(ChildFoo oldChild)
    {
        DoRemoveLogic(oldChild);
        _Children.Remove(oldChild);
        NotifyPropertyChange("Children");
    }

    public ChildFoo[] Children
    {
        get
        {
            return _Children.ToArray();
        }
    }

}

我没有看到这种设计存在严重缺陷吗?

每次访问Children属性时,我们都会将列表转换为数组。

对此的任何建议都会很棒。

4 个答案:

答案 0 :(得分:5)

这就是我为普通代码所做的事情:

Public Readonly Property Childern As ObjectModel.ReadOnlyCollection(Of Child)
    Get
       Return New ObjectModel.ReadOnlyCollection(Of Child)(_ChildernList)
    End Get
End Property

对于WPF代码,我只公开一个ObservableCollection的子类。

答案 1 :(得分:0)

我将“添加子项”和“删除子项”更改为受保护,因为您说您不希望其他类修改您的集合。我将List更改为ObservableCollection,以便您可以收到集合更改的通知。由于您使用的是IList,因此无需调用ToArray(),只需直接访问即可。

试试这个:

public class foo : INotifyPropertyChanged
{
    protected ObservableCollection<ChildFoo> _Children = new ObservableCollection<ChildFoo>();

public foo()    {    }

protected void AddChild(ChildFoo oldChild)
{
    DoAttachLogic(newChild);
    _Children.Add(newChild);
    NotifyPropertyChange("Children");
}

protected void RemoveChild(ChildFoo oldChild)
{
    DoRemoveLogic(oldChild);
    _Children.Remove(oldChild);
    NotifyPropertyChange("Children");
}

public ChildFoo this[int n]
{
    get
    {
        return _Children[n];
    }
}

}

答案 2 :(得分:0)

您可以将BindingList子类化并将AllowNew / AllowRemove设置为false。在Child Add / Remove方法中,您可以将其设置为true,进行更改,然后将其设置为false。 (当然,您还需要隐藏来自外部呼叫者的AllowNew / AllowRemove的设置访问权限。)

另一个选项 - 子类Observable集合并覆盖InsertItem,RemoveItem等方法,表现为AddChild / RemoveChild的行为。然后调用者仍然可以熟悉的方式访问它,但不会绕过您的自定义逻辑。

对现有集合类进行子类化(对于您和使用者而言)可能比将集合包装在另一个类中更容易。

答案 3 :(得分:0)

您应该在类中使用ObservableCollection作为字段,然后您可以完全访问修改集合。然后通过属性将其公开为ReadonlyObservableCollection。 如果你不改变集合本身(例如,没有children = new ObservableCollection(),你应该只读字段),那么你不需要在这个属性上任何类型的notifyPropertyChanged,因为它没有改变,集合本身为它的子节点处理那些事件。

public class Child
{
    public int Value { get; set; }
}

class MyClassWithReadonlyCollection
{
    private readonly ObservableCollection<Child> _children = new ObservableCollection<Child>();

    public MyClassWithReadonlyCollection()
    {
        _children.Add(new Child());
    }

    //No need to NotifyPropertyChange, because property doesnt change and collection handles this internaly
    public ReadOnlyObservableCollection<Child> Children { get { return new ReadOnlyObservableCollection<Child>(_children); } }
}
相关问题