Reputation: 23
I'm designing a database interface, and am writing a method to add a table to the database. Different databases may need different parameters to add tables, so to solve that, I've made an abstract class for database parameters. An example which uses GoogleSheets:
public abstract class DatabaseTableParameters
{
public string Key { get; set; }
public DatabaseTableParameters(string key) {
Key = key;
}
}
public class GoogleSheetParameters : DatabaseTableParameters
{
public int RangeColumnStart { get; set; }
public int RangeRowStart { get; set; }
public int RangeColumnEnd { get; set; }
public bool FirstRowIsHeaders { get; set; }
public GoogleSheetParameters(string key, int columnStart, int rowStart, int columnEnd, bool firstRowIsHeaders = false) : base(key)
{
RangeColumnStart = columnStart;
RangeRowStart = rowStart;
RangeColumnEnd = columnEnd;
FirstRowIsHeaders = firstRowIsHeaders;
}
}
The interface then has a method for adding a table to the database.
interface IDatabase<T>
{
void AddTable(DatabaseTableParameters param);
}
The problem is that implementations of the database need to be restricted to a certain subclass of DatabaseTableParameters. I could use reflection to ensure that the passed parameter is the correct type, but that seems a little fragile to me.
Is there a better was of ensuring the correct parameter type is passed in?
Upvotes: 0
Views: 67
Reputation: 52210
Define your table parameters with a constraint that identifies what table type it goes with.
public abstract class DatabaseTableParameters<T>
{
public string Key { get; set; }
public DatabaseTableParameters(string key) {
Key = key;
}
}
public class GoogleSheetParameters : DatabaseTableParameters<GoogleTable>
{
//Etc...
Then define your database using this constraint:
interface IDatabase<T>
{
void AddTable<T>(DatabaseTableParameters<T> param);
}
class GoogleSheetDatabase : IDatabase<GoogleTable>
{
//etc....
This will force the Add
method to require the appropriate type of parameters at compile time.
Upvotes: 1
Reputation: 16652
Something like this, you can add Table1
but not Table2
thanks to where
public interface ITable
{
string Key { get; set; }
}
public abstract class TableBase : ITable
{
public string Key { get; set; }
}
public interface ITableExt
{
int A { get; set; }
string Key { get; set; }
}
public class Table1 : TableBase, ITableExt
{
public int A { get; set; }
}
public class Table2 : TableBase
{
public int A { get; set; }
}
class Test
{
public Test()
{
Add(new Table1());
// Add(new Table2()); // not possible
}
public void Add<T>(T value) where T : TableBase, ITableExt
{
}
}
Upvotes: 0