I'm trying to get something working and struggling with the below when using Contravariance. My understanding is Covariance is where you can return a derived type from a base type. Contravariance is where you can pass in a derived type from a base type as an argument into a class.
So I have the below interface (contravariant):
public interface IBase<in T> where T: BaseModel
{
void Process(T model);
}
I then have an abstract class
public abstract class Base<T>: IBase<T> where T: BaseModel
{
public virtual void Process(T model)
{
// throw new System.NotImplementedException();
}
}
and another concrete class
public class Parent: Base<ParentModel>
{
public override void Process(ParentModel model)
{
// throw new System.NotImplementedException();
}
}
Considering the generic type is only ever used as an input and not a return type, I don't see why I cannot do the below:
IBase<BaseModel> baseContravariant = new Parent();
// This doesn't compile. I will eventually have a list of IBase<BaseMode> to which I'd like to pass in different parent instances.
I have another example using covariance which is below and works fine.
public interface IBase<out T> where T : BaseModel, new()
{
T ProcessAndGet();
}
Abstract
public abstract class Base<T>: IBase<T> where T: BaseModel, new()
{
public virtual T ProcessAndGet()
{
var result = new T() as BaseModel;
// More shizzle here
return (T)result;
}
}
Concrete
public class Parent : Base<ParentModel>
{
public override ParentModel ProcessAndGet()
{
var x = base.ProcessAndGet();
return x;
}
}
Now I can do
IBase<BaseModel> baseInstance = new Base<BaseModel>();
IBase<BaseModel> derived = new Parent();
baseInstance = derived;
There's more code to the above examples but I've removed it for ease of reading (hopefully!) :-)