I have a set of interfaces using each others like this:
public interface IModel
{
string Name { get; }
IModelParameters Parameters { get; }
}
public interface IModelParameter
{
int Value { get; }
}
public interface IModelParameters: IList<IModelParameter>
{
void DoSomething();
}
And to implement those interfaces, I have defined those classes:
public class Model: IModel
{
string Name { get; internal set; }
public ModelParameters Parameters { get; private set; }
IModelParameters IModel.Parameters { get { return Factors; } }
}
public class ModelParameter: IModelParameter
{
int Value { get; internal set; }
}
public class ModelParameters: List<ModelParameter>, IModelParameters
{
void DoSomething()
{
// actual code
}
}
This does not compile because List<ModelParameter>
implements IList<ModelParameter>
and not IList<IModelParameter>
as required by IModelParameters
Changing ModelParameters
to be List<IModelParameter>
fixes the compilation but it breaks Entity Framework migration generation because it no longer recognizes the list as a navigation property because the type parameter is an interface, not a regular class.
I could also have ModelParameters
not implement IModelParameters
and declare a second class that gets instantiated and filled directly in the IModelParameters.Factors
getter inside Model
But this feels inefficient as it effectively creates two instances of the same list, one for Entity framework and a temporary one for use by the rest of the application. And because this temporary is filled at runtime, it introduces another potential point of failure.
This is why I'm trying to find a way to express the fact List<ModelParameter>
implements IList<IModelParameter>
just fine because ModelParameter
implements IModelParameter
itself.
I have a feeling that covariance/contravariance might be of help here, but I'm not sure how to use that.