我有一个名为Items of List的复合属性到一个订单类。在GUI上,用户填写一些字段,如名称,描述,价格,数量等...然后单击添加项目按钮,当然将项目添加到订单的项目列表中。我想要做的是创建一个检查项目的IsComplete属性的方法,该属性进行检查以确保设置所需的属性,这样有人不能只调用order.Items.Add(item)如果不是完成。如果不是我想在项目的IsComplete属性返回false时抛出异常......什么是简单的方法呢?
答案 0 :(得分:1)
这可以通过将List<T>
子类化为派生类,然后覆盖Add
方法来实现。
public class MyItemCollection : List<MyItem>
{
public override void Add(MyItem item)
{
if (item.IsComplete)
{
base.Add(item);
}
else
{
throw new InvalidOperationException("Unable to add an incomplete item");
}
}
}
您的订单类将拥有属性MyItemCollection
而不是List<T>
,如下所示:
public class Order
{
public MyItemCollection Items { get; set; }
}
答案 1 :(得分:0)
您还可以使用ObservableCollection<T>
:http://msdn.microsoft.com/en-us/library/ms668604.aspx
它实现了INotifyCollectionChanged
:http://msdn.microsoft.com/en-us/library/System.Collections.Specialized.INotifyCollectionChanged.aspx
答案 2 :(得分:0)
由于方法Add(T)
不是虚拟的,因此您无法覆盖它。
ObservableCollection允许在添加元素时抛出事件但不撤消此添加。
您可以使用IList<T>
存储internaly来实现界面List<T>
,并在调用Add(T item)
之前在方法_list.Add(item)
中添加所需的验证,如下例所示:< / p>
public class MyItemCollection : IList<MyItem>
{
private List<MyItem> _list;
public MyItemCollection()
{
_list = new List<MyItem>();
}
public void Add(MyItem item)
{
if (item.IsComplete)
{
_list.Add(item);
}
else
{
throw new InvalidOperationException("Unable to add an incomplete item");
}
}
//Then you have to implement all the IList interface members...
}
此解决方案的唯一问题是需要编写大量样板代码。
如果只有一个类负责操纵List
,您还可以决定在负责类中实现方法AddToMyItemCollection(MyItem item)
。它甚至是一个很好的实践,因为它尊重GRASP模式protected variation(Instance.getC()优于Instance.getA()。getB()。getC())