'Can I pass a base class type as a generic parameter to an interface
Can I pass base class types as a generic parameters to interfaces which are implemented in the context of the successors of that base class in C#.
Let's imagine there is an interface:
public interface IElement<T>
{
Collection<T> Neighbors { get; }
}
I want to implement this interface like this:
public class Element : IElement<object>
{
public Collection<Neighbor> Neighbors { get; set; }
}
I also even tried achieving it like this:
public class Element : IElement<IObject>
{
public Collection<Neighbor> Neighbors { get; set; }
}
Where IObject and Neighbor are:
public interface IObject
{
}
public class Neighbor : IObject
{
// some props
}
In either way I get the same error: Element does not implement the IElement interface - member Neighbors cannot implement IElement.Neighbors, because they have different return types.
The purpose of this is to make an abstraction of the datatypes and use a simpler version of them in the business logic:
public class BusinessLogic
{
bool predicate1;
bool predicate2;
// variant 1
public bool CanIDoSomething(IElement<object> element)
{
return element.Neighbours.Any() && predicate1 && predicate2;
}
// variant 2
public bool CanIDoSomething(IElement<IObject> element)
{
return element.Neighbours.Any() && predicate1 && predicate2;
}
}
The problem goes even deeper if I try to use IEnumerable instead of Collection:
public interface IElement<T>
{
IEnumerable<T> Neighbors { get; }
}
What am I missing and is there a workaround for this?
EDIT:
I Made the IElement interface generic parameter covariant as follows:
public interface IElement<out T>
{
IEnumerable<T> Neighbors { get; }
}
But this does not solve the interface implementation error.
The only way I can make the class to implement the interface correctly is by doing this:
public class Element : IElement<IObject>
{
public Collection<Neighbor> Neighbors { get; set; }
IEnumerable<IObject> IElement<IObject>.Neighbors => Neighbors;
}
Is there a limitation that causes the covariance to not be applied implicitly when implementing an interface?
Is there a more elegant way of doing this?
I want to keep the IObject interface instead of using object directly because in the IObject interface if I ever need I can place a certain subset of the properties of the Neighbor class.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
