I am still trying to fully understand generics especially when used in conjunction with base classes. I have a generic table class that takes in a derived type of a row class but is constrained to be a base row. Since the base table class is constraint to taking a type base row how can I pass this class with any derived class to be of base row type.
public interface Itable<in TRow> where TRow : row{
//*This will not compile with the list of TRow should it be List<row>? If so how do i force that conversion?
List<TRow> IfindLst();
}
public abstract class table<TRow> where TRow : row, Itable<row>
{
//*This is the list of rows i want to be able to send as their base row
public List<TRow> derivedRowLst = new List<TRow>();
public table()
{
}
public List<row> IfindLst()
{
return derivedRowLst;
}
}
//Derive instance of base table class
public class tableInstOne : table<rowInstOne>
{
}
//Base class for row that all derived rows are guarantee to be of
public abstract class row
{
}
public class rowInstOne : row
{
public rowInstOne() { }
}
public class tester
{
public static void main()
{
Itable<row> tblInstOne = new tableInstOne();
//*This is what I am trying to figure out how to do get this list of base row class from the base table class. Even though it is stored as List<TRow> or derived row class.
List<row> baseLst = tblInstOne.IfindLst();
}
}
This does not allow me to send the instantiated table class as having its base guaranteed type. I used to not have the table class as generic and so all rows were just used as base row but this required downcasting at other points in code that I am trying to avoid. Now I don't have to downcast BUT I cannot send this table class with base as a parameter to classes that don't care about the derived row type and only need to utilize the base row functions. Thanks for any help!
It is hard to tell exactly what you are trying to accomplish. Perhaps the following code will help. Note that the method IfindLst
returns a List<TRow>
rather than a List<Row>
, which I think may be part of your problem.
public abstract class Table<TRow> where TRow : Row
{
//*This is the list of rows i want to be able to send as their base row
public List<TRow> derivedRowLst = new List<TRow>();
public Table()
{
}
public List<TRow> IfindLst()
{
return derivedRowLst;
}
}
//Derive instance of base table class
public class TableInstOne : Table<RowInstOne>
{
}
//Base class for row that all derived rows are guarantee to be of
public abstract class Row
{
}
public class RowInstOne : Row
{
public RowInstOne() { }
}
public static class Program
{
public static void Main(string[] args)
{
Table<RowInstOne> tblInstOne = new TableInstOne();
//*This is what I am trying to figure out how to do get this list of base row class from the base table class. Even though it is stored as List<TRow> or derived row class.
List<Row> baseLst = tblInstOne.IfindLst().OfType<Row>().ToList();
List<Row> baseLst2 = tblInstOne.IfindLst().ConvertAll(x => (Row)x);
List<Row> baseLst3 = tblInstOne.IfindLst().Cast<Row>().ToList();
IEnumerable<Row> baseLst3 = tblInstOne.IfindLst();
}
}
Note on the last line I demonstrate the use of the covariant IEnumerable<T>
interface to avoid any casting or runtime type-checking.