首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何避免实现所有IList成员,并且仍然有一个实现集合的基本接口?

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

Stack Overflow用户
提问于 2011-06-15 06:01:43
回答 3查看 391关注 0票数 0

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

目前,我正在做以下工作:

代码语言:javascript
复制
public interface IAddressCollection : IList<IAddress>
{
      new void Add(IAddress address);    
}

因此,我必须实现所有的东西,类似于下面的代码。我想避免这样做,我在寻找一个简单的方法。

代码语言:javascript
复制
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

EDIT******

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

此外,“问题到底是什么”,你怎么能得到5票呢?说真的,如果他给了我半个像样的答案,我会投他/她一票,而不是对一个问题投赞成票。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-06-15 06:10:08

最常见的方法是从Collection<T>派生

代码语言:javascript
复制
public class AddressCollection : Collection<IAddress>, IAddressCollection
{
    public AddressCollection() : base(new List<IAddress>())
    {
    }
}

Collection<T>实现了IList<T>

更新以响应评论。

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

每当调用公共AddInsert方法向列表中添加元素时,都会调用Add。类似地,在替换元素时调用SetItem (myCollection[index] = newValue),在调用公共Remove方法时调用RemoveItem,在调用公共Clear方法时调用ClearItems

通过这样做,您将解决Florian在注释中提出的问题--您的自定义逻辑将始终被执行,即使列表被多形性地用作IList<IAddress>Collection<IAddress>

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

代码语言:javascript
复制
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 ...
}
票数 5
EN

Stack Overflow用户

发布于 2011-06-15 06:09:19

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

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

代码语言:javascript
复制
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
}
票数 2
EN

Stack Overflow用户

发布于 2011-06-15 06:14:02

尝试使用扩展方法。你可能会想出一个更好的名字。

代码语言:javascript
复制
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;
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6353669

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档