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

Nic*_*ckz 0 c# list

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

目前我正在做以下事情:

public interface IAddressCollection : IList<IAddress>
{
      new void Add(IAddress address);    
}
Run Code Online (Sandbox Code Playgroud)

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

public class AddressCollection : IAddressCollection
{
    private List<IAddress> _data = new List<IAddress>();

    new public void Add(IAddress applicationAddress)
    {
        // some logic here... e.g.
        if (!this.Any(x => x.AddressType != applicationAddress.AddressType))
        {
            _data.Add(applicationAddress);
        }
    }
    // Plus all the members of IList
Run Code Online (Sandbox Code Playgroud)

编辑******

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

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

Joe*_*Joe 5

最常见的方法是从Collection<T>以下方面得出:

public class AddressCollection : Collection<IAddress>, IAddressCollection
{
    public AddressCollection() : base(new List<IAddress>())
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

Collection<T>实施IList<T>.

更新以回应评论.

如果要实现自定义逻辑添加或删除项目时,最好重写的受保护的虚拟一种或多种方法InsertItem,SetItem,RemoveItemClearItems,而不是实现一个新的Add方法.

InsertItem只要调用public AddInsertmethod将元素添加到列表中,就会调用它.类似的SetItem是在替换元素时调用(myCollection[index] = newValue),RemoveItem在调用公共Remove方法时调用以及调用ClearItems公共Clear方法时调用.

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

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

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 ...
}
Run Code Online (Sandbox Code Playgroud)

  • 感谢Joe,这正是我所寻找的,我很欣赏这个例子. (3认同)
  • 没有不尊重你可以,我已经实现了Joe代码,我已经在我的示例中创建了一个新方法,并且它完美地工作而无需创建一个util类,例如new public void Add(IAddress address){..相同的逻辑代码..}我不需要创建私有变量和额外的噪音.这是理想和正确的方法,我只是在一年多的时间里没有写过这些类型的数据合同. (3认同)
  • 我没有考虑扩展方法,因为我将通过WCF将dataContract传递给客户端可能不关心实现,我不想也提供带有datacontracts的扩展库.我用"理想"的方式跳了起来,但感谢@FlorianGreinacher非常好,并感谢您的反馈.我可能需要重新考虑扩展方法. (2认同)