Possible Duplicate:
Casting List<T> - covariance/contravariance problem
I have classes defined as below
public abstract class AbstractDType
{
protected abstract string Num1 { get; set; }
protected abstract string Num2 { get; set; }
}
public class AD1 : AbstractDType
{
public string Num1 { get; set; }
public string Num2 { get; set; }
public string Num3 { get; set; }
}
public class AD2 : AbstractDType
{
public string Num1 { get; set; }
public string Num2 { get; set; }
public string Num3 { get; set; }
}
public abstract class DTypeStrategy
{
protected virtual List<AbstractDType> GetData()
{
return new List<AD1>();
}
}
I would like to return a list of PD1 (concrete type) in GetData() method. However the above code threw a casting error . List<AbstractDType>
cannot be converted to List<PD1>
. How do I fix this error so that I could return concrete in GetData method.
There are other derived classes that inherited from DTypeStrategy which would be implementing GetData() such as below : ( I am assuming that I'll get the same casting error here as well )
public class MyDraw : DTypeStrategy
{
public override List<AbstractDType> GetData()
{
return new List <AD2>();
}
}
What is your actual goal here? If you really just want to return a list from GetData that contains AD1, you can do that:
protected virtual List<AbstractDType> GetData()
{
var stuff = new List<AbstractDType>();
stuff.Add( new AD1() );
return stuff;
}
But if you really want to return a list of a concrete type, then, well, you can't do that - and it points to a flaw in your design. Think of the calling code if this were possible:
public void Victim(DTypeStrategy strat)
{
List<AbstractDType> list = strat.GetData();
//oops, the list is actually a list<AD1>, so this throws:
list.Add( new AD2() );
}
Ask yourself:
If you MUST have a specialized List for some reason, use a generic method:
public class DTypeStrategy<T> where T: AbstractDType
{
//not sure a concrete here is a good idea, but you get the point...
public virtual List<T> GetData()
{
return new List<T>();
}
}
public class MyDraw : DTypeStrategy<AD2>
{
public override List<AD2> GetData()
{
return new List<AD2>();
}
}
If you don't need a List<T>
, then you can probably abuse c#'s covariant generic interfaces to do this - but again, I'd look at your design first.
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