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