简体   繁体   中英

Do a check when List.Add method is called

I have a composite property called Items of type List to an order class. On the GUI the user fills out some fields like Name, Description, Price, Quantity, etc... and then clicks the Add Item button which of course adds the item to the order's list of items. What I'd like to do is create a method that checks the item's IsComplete property which does a check to ensure the required properties are set so that way someone can't just call order.Items.Add(item) if it isn't complete. If it's not I'd like an exception to be thrown if the item's IsComplete property returns false... What would be an easy way to go about this?

This can be achieved by sub-classing List<T> into a derived class, and then overriding the Add method, like so.

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");
        }
    }
}

Your order class would then have the property MyItemCollection rather than List<T> , like so:

public class Order
{
    public MyItemCollection Items { get; set; }
}

Since the method Add(T) is not virtual you can't override, it.

ObservableCollection allow to throw an event when an element was added but not to undo this add.

You can implement the interface IList<T> with a List<T> storred internaly and add the desired verification in the method Add(T item) before calling the _list.Add(item) like in the exemple below :

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...

}

The only problem with this solution is that it require to write a lot of boilerplate code.

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())

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM