Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# can you hide an inherited interface?

I have a set of interfaces and classes that look something like this:

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; }
}

The problem I run into is when I try use Linq on my ItemCollection, it gets confused because there are two IEnumerable interfaces.

I get the following error message:

The type arguments for method 'System.Linq.Enumerable.Where(...) cannot be inferred from the usage. Try specifying the type arguments explicitly.

Is there any way to hide the "more primitive" IEnumerable<IItem> interface so it will always choose the IEnumerable<TItem> when dealing with the ItemCollection<,>, but still provide the IEnumerable<IItem> interface when dealing with IItemCollection interface?


(As I'm about to post this, I realized that there's a workaround, to implement it like this:

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

But I still want to know if there's a way to hide an interface.)

like image 950
Bryce Wagner Avatar asked Aug 12 '14 21:08

Bryce Wagner


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

What is C in C language?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.

Is C language easy?

Compared to other languages—like Java, PHP, or C#—C is a relatively simple language to learn for anyone just starting to learn computer programming because of its limited number of keywords.

What is C full form?

History: The name C is derived from an earlier programming language called BCPL (Basic Combined Programming Language). BCPL had another language based on it called B: the first letter in BCPL.


1 Answers

Perhaps you could achieve what you want with a little bit of composition instead of inheritance:

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>(); }
}

We can change IItemCollection so that it returns an IEnumerable<IItem> instead of implementing IEnumerable<IItem>. Now your concrete class can implement all interfaces and you don't need abstract classes.

like image 126
Joseph Daigle Avatar answered Oct 06 '22 00:10

Joseph Daigle