簡體   English   中英

C#可以隱藏繼承的接口嗎?

[英]C# can you hide an inherited interface?

我有一組接口和類看起來像這樣:

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 <IItem>接口,所以它在處理ItemCollection <,>時總會選擇IEnumerable <TItem>,但在處理IItemCollection接口時仍然提供IEnumerable <IItem>接口?


(正如我即將發布的那樣,我意識到有一種解決方法,就像這樣實現它:

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

但是我仍然想知道是否有隱藏界面的方法。)

也許你可以通過一點點組合而不是繼承來實現你想要的東西:

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替代原則的聰明設計(如果有的話)

使用指針或對基類的引用的函數必須能夠在不知道它的情況下使用派生類的對象。

作為一個比我聰明的人曾經說過“不要讓你的設計變得聰明,親吻。”

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM