确保接口实现具有正确的方法子类

时间:2021-02-25 00:13:56

标签: c# .net

我正在设计一个数据库接口,并且正在编写一个向数据库添加表的方法。不同的数据库可能需要不同的参数来添加表,因此为了解决这个问题,我为数据库参数创建了一个抽象类。使用 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;
    }
}

然后接口有一个方法来向数据库添加一个表。

interface IDatabase<T>
{
    void AddTable(DatabaseTableParameters param);

}

问题是需要将数据库的实现限制为 DatabaseTableParameters 的某个子类。我可以使用反射来确保传递的参数是正确的类型,但这对我来说似乎有点脆弱。

是否有更好的方法确保传入正确的参数类型?

2 个答案:

答案 0 :(得分:1)

使用一个约束来定义你的表参数,该约束标识它所使用的表类型。

public abstract class DatabaseTableParameters<T> 
{
    public string Key { get; set; }

    public DatabaseTableParameters(string key) {
        Key = key;
    }
}

public class GoogleSheetParameters : DatabaseTableParameters<GoogleTable>
{
    //Etc...

然后使用此约束定义您的数据库:

interface IDatabase<T>
{
    void AddTable<T>(DatabaseTableParameters<T> param);
}


class GoogleSheetDatabase : IDatabase<GoogleTable>
{
    //etc....

这将强制 Add 方法在编译时需要适当类型的参数。

答案 1 :(得分:0)

像这样,你可以添加 Table1 但不能添加 Table2 多亏了 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
    {

    }
}