我有一个名为 List 类型的 Items 的复合属性到一个订单类。在 GUI 上,用户填写一些字段,如名称、描述、价格、数量等......然后单击添加项目按钮,这当然会将项目添加到订单的项目列表中。我想做的是创建一个方法来检查项目的 IsComplete 属性,该属性会检查以确保设置了所需的属性,这样如果不是,某人就不能只调用 order.Items.Add(item)完全的。如果不是,我希望在项目的 IsComplete 属性返回 false 时引发异常......有什么简单的方法来解决这个问题?
3 回答
这可以通过子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; }
}
您还可以使用ObservableCollection<T>
: http: //msdn.microsoft.com/en-us/library/ms668604.aspx
它实现了:http INotifyCollectionChanged
: //msdn.microsoft.com/en-us/library/System.Collections.Specialized.INotifyCollectionChanged .aspx
由于该方法Add(T)
不是虚拟的,因此您无法覆盖它。
ObservableCollection 允许在添加元素时引发事件,但不能撤消此添加。
您可以IList<T>
使用存储的List<T>
内部实现接口,并在方法中添加所需的验证,Add(T item)
然后在下面的示例中调用_list.Add(item)
类似:
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...
}
此解决方案的唯一问题是它需要编写大量样板代码。
If only one class is responsible of the manipulation of your List
, you can also decide to implement a method AddToMyItemCollection(MyItem item)
in the responsible class. It is even a good practive as it's respect the GRASP pattern protected variation (Instance.getC() is preferable to Instance.getA().getB().getC())