manny_33

I recently coded a stored procedure generator. I decided to create abstract base clases and improve the architecture of the program. My base classes are:
  • Column
  • ColumnCollection<T> : ICollection<T> where T : Column
  • Table<T> where T : ColumnCollection<Column>
The classes I use to represent Sql Server structures are:
  • SqlServerColumn : Column
  • SqlServerColumnCollection : ColumnCollection<SqlServerColumn>
  • SqlServerTable : Table<SqlServerColumnCollection>
I get an error that says (at compile time):
The type 'TestSqlGenerator.SqlServerColumnCollection' must be convertible to 'TestSqlGenerator.ColumnCollection<TestSqlGenerator.Column>' in order to use it as parameter 'T' in the generic type or method 'TestSqlGenerator.Table<T>'

I have a temporary fix:
Table<T,U> where T : ColumnCollection<U> where U : Column

but that would force me to use a declaration like:
SqlServerTable : Table<SqlServerColumnCollection,SqlServerColumn>

Here i have to specify that SqlServerColumnCollection is of SqlServerColumn, which is reapeating a type that SqlServerColumnCollection already knows it is.

Implicit conversion operators don't work is there any way to convert SqlServerColumnCollection to ColumnCollection<TestSqlGenerator.Column>


Re: Visual C# Language Problem with Generics

Chuck the Code Monkey

Try this:

class Column {...}
class ColumnCollection<T> : ICollection<T> where T : Column {...}
class ColumnTable<T> where T : ColumnCollection<Column> {...}

class SqlServerColumn : Column {...}
class SqlServerColumnCollection : ColumnCollection<Column> {...}
class SqlServerColumnTable : ColumnTable<SqlServerColumnCollection> {...}

SqlServerColumnCollection works because it's still a collection of Columns since SqlServerColumn inherits from Column.





Re: Visual C# Language Problem with Generics

manny_33

 Chuck the Code Monkey wrote:
Try this:

class Column {...}
class ColumnCollection<T> : ICollection<T> where T : Column {...}
class ColumnTable<T> where T : ColumnCollection<Column> {...}

class SqlServerColumn : Column {...}
class SqlServerColumnCollection : ColumnCollection<Column> {...}
class SqlServerColumnTable : ColumnTable<SqlServerColumnCollection> {...}

SqlServerColumnCollection works because it's still a collection of Columns since SqlServerColumn inherits from Column.


Here you don't use SqlServerColumn as the type in
SqlServerColumnCollection.
this elminates the need of casting SqlServerColumn to Column at the moment
of declaring the table, but I would have to cast Column to SqlServerColumn when i need something specific from SqlServerColumn.





Re: Visual C# Language Problem with Generics

James Curran

SqlServerColumnCollection works because it's still a collection of Columns since SqlServerColumn inherits from Column.

But that merely gives you the new problem of the items in your SqlServerColumnCollection being Columns instead of SqlServerColumns.






Re: Visual C# Language Problem with Generics

James Curran

This can be done, if you make ColumnCollection a public inner class of Column<T>



class Column<T> where T : Column<T>
{
public class ColumnCollection : ICollection<T>
{
}
}
class Table<T> where T : Column<T>
{
}
class SqlColumn : Column<SqlColumn>
{}
class SqlColumnCollection : Column<SqlColumn>.ColumnCollection
{}
class SqlTable : Table<SqlColumn>
{}