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.)
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? 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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With