所以我有这些类暴露了一组子对象。
我不希望其他类在集合中添加或删除对象,因为我需要连接到子对象中的事件,因此当它们被添加或删除时,我希望能够进行其他处理。但我真的很喜欢内部操纵泛型的简易性。
我是否提到这是一个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属性时,我们都会将列表转换为数组。
对此的任何建议都会很棒。
答案 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); } }
}