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

如何实现更简单的解决方案,我正在寻找一种更好的方法,而不是必须创建一个复杂的实现类,欣赏一些建议。

目前我正在做以下事情:

public interface IAddressCollection : IList { new void Add(IAddress address); } 

所以我必须实现类似下面代码的所有内容。 我想避免这样做,我正在寻找一种简单的方法。

 public class AddressCollection : IAddressCollection { private List _data = new List(); new public void Add(IAddress applicationAddress) { // some logic here... eg if (!this.Any(x => x.AddressType != applicationAddress.AddressType)) { _data.Add(applicationAddress); } } // Plus all the members of IList 

编辑* * ****

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

此外,你怎么能得到5票“准确的问题是什么?” 说真的,如果他给了我一个不错的答案,我会给他/她投票,但不是问题的问题。

最常见的方法是从Collection派生:

 public class AddressCollection : Collection, IAddressCollection { public AddressCollection() : base(new List()) { } } 

Collection实现IList

更新以回应评论。

如果要在添加或删除项目时实现自定义逻辑,最好覆盖一个或多个受保护的虚拟方法InsertItemSetItemRemoveItemClearItems ,而不是实现新的Add方法。

只要调用公共的AddInsert方法将元素添加到列表中,就会调用InsertItem 。 类似地,在替换元素时调用SetItemmyCollection[index] = newValue ),调用公共Remove方法时调用RemoveItem ,调用公共Clear方法时调用ClearItems

通过这样做,您将解决Florian Greinacher在评论中提出的问题 – 即使列表以多态方式用作IListCollection您的自定义逻辑也将始终执行

例如,要匹配您的示例,您可以忽略插入/设置与谓词不匹配的项目,其代码类似于以下(未经测试):

 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 eg throw an exception } } protected override void SetItem(int index, IAddress newItem) { ... etc ... } 

为什么要隐藏在IList声明的void Add(T item)方法? 只需从IAddressCollection删除该方法,一切都会正常工作。

您的实现类可以如下所示:

 public class AddressCollection : IAddressCollection { private List _data = new List(); 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 list, IAddress applicationAddress) { if (!list.Any(x => x.AddressType != applicationAddress.AddressType)) { list.Add(applicationAddress); return true; } return false; } }