如何避免实现所有IList成员,并且仍然具有实现集合的基本接口?

问题描述

|                                                                                                                       

解决方法

        最常见的方法是从ѭ0派生:
public class AddressCollection : Collection<IAddress>,IAddressCollection
{
    public AddressCollection() : base(new List<IAddress>())
    {
    }
}
Collection<T>
实现
IList<T>
。 更新以回应评论。 如果要在添加或删除项目时实现自定义逻辑,最好重写一个或多个受保护的虚方法
InsertItem
SetItem
RemoveItem
ClearItems
,而不是实现新的
Add
方法。 每当调用公共
Add
Insert
方法向列表中添加元素时,都会调用
InsertItem
。类似地,当元素被替换时(
myCollection[index] = newValue
),
SetItem
被调用;调用公共public15ѭ方法时,called6ѭ被调用;当公共public17ѭ方法被调用时,
ClearItems
被调用。 通过这样做,您将解决Florian Greinacher在注释中提出的问题-即使列表以多态形式用作
IList<IAddress>
或ѭ19used,您的自定义逻辑也将始终执行 例如,要匹配您的示例,您可以忽略插入/设置与以下谓词不匹配谓词的项目(未经测试):
protected override void InsertItem(int index,IAddress newItem)
{
    if (!this.Any(x => x.AddressType != newItem.AddressType)
    {
        base.InsertItem(index,newItem);
    }
    else
    {
        // ... item does not match,do whatever is appropriate e.g. throw an exception
    }
}

protected override void SetItem(int index,IAddress newItem)
{
    ... etc ...
}
    ,        为什么要隐藏
IList<T>
中声明的方法
void Add(T item)
?只需从
IAddressCollection
中删除该方法,一切正常。 然后,您的实现类可以如下所示:
public class AddressCollection : IAddressCollection
{
    private List<IAddress> _data = new List<IAddress>();

    public void Add(IAddress applicationAddress)
    {
        if (!this.Any(x => x.AddressType != applicationAddress.AddressType))
        {
            _data.Add(applicationAddress);
        }
    }

    // Plus all other members of IAddressCollection
}
    ,        尝试使用扩展方法。您可能想提出一个更好的名称。
public static class ListExtensions 
{
    public static bool TryAdd(this IList<IAddress> list,IAddress applicationAddress)
    {
        if (!list.Any(x => x.AddressType != applicationAddress.AddressType))
        {
            list.Add(applicationAddress);
            return true;
        }
        return false;
    }
}