c#可以隐藏继承的接口

本文关键字:接口 继承 隐藏 | 更新日期: 2023-09-27 18:17:46

我有一组接口和类,看起来像这样:

public interface IItem
{
    // interface members
}
public class Item<T> : IItem
{
    // class members, and IItem implementation
}
public interface IItemCollection : IEnumerable<IItem>
{
    // This should be enumerable over all the IItems
}
// We cannot implement both IItemCollection and IEnumerable<TItem> at
// the same time, so we need a go between class to implement the
// IEnumerable<IItem> interface explicitly:
public abstract class ItemCollectionBase : IItemCollection
{
    protected abstract IEnumerator<IItem> GetItems();
    IEnumerator<IItem> IEnumerable<IItem>.GetEnumerator() { return GetItems(); }
    IEnumerator IEnumerable.GetEnumerator() { return GetItems(); }
}
public class ItemCollection<TKey, TItem> : ItemCollectionBase, IEnumerable<TItem>
    where TItem : class,IItem,new()
{
    private Dictionary<TKey, TItem> dictionary;
    protected override GetItems() { return dictionary.Values; }
    public IEnumerator<TItem> GetEnumerator() { return dictionary.Values; }
}

我遇到的问题是,当我尝试在我的ItemCollection上使用Linq时,它会混淆,因为有两个IEnumerable接口。

我得到以下错误信息:

方法System.Linq.Enumerable.Where(…)的类型参数不能从用法中推断出来。尝试显式指定类型参数。

是否有办法隐藏"更原始"的IEnumerable接口,所以它总是会选择IEnumerable在处理ItemCollection<时,但仍然提供IEnumerable>接口时处理IItemCollection接口?


(当我即将发布这篇文章时,我意识到有一个解决方案,可以像这样实现它:

public interface IItemCollection
{
    IEnumerable<IItem> Items { get; }
}

但是我仍然想知道是否有一种方法可以隐藏接口

c#可以隐藏继承的接口

也许你可以用一点组合而不是继承来达到你想要的效果:

public interface IItem
{
    // interface members
}
public class Item<T> : IItem
{
    // class members, and IItem implementation
}
public interface IItemCollection
{
    IEnumerable<IItem> GetItems();
}    
public class ItemCollection<TKey, TItem> : IItemCollection, IEnumerable<TItem>
    where TItem : class,IItem,new()
{
    private Dictionary<TKey, TItem> dictionary;
    public IEnumerator<TItem> GetEnumerator() { return dictionary.Values; }
    public IEnumerable<IItem> GetItems() { return dictionary.Values.Cast<IItem>(); }
}

我们可以改变IItemCollection,使其返回IEnumerable<IItem>而不是实现IEnumerable<IItem>。现在,您的具体类可以实现所有接口,而不需要抽象类。

我认为你正在走向一个聪明的设计(如果有的话),违反了Liskov替代原则

使用指针或基类引用的函数必须能够在不知情的情况下使用派生类的对象。

就像一个比我聪明的人曾经说过的:"不要让你的设计太聪明,KISS。"