1

这应该不难回答,但我非常绝望和困惑。我制作了从数据库执行读取查询的接口

interface IDatabase
{
    DataTable ExecuteReaderCommand(IDbCommand command);
    IDbCommand GetNewCommand();
}

接下来,我在接口上面创建了两个不同的类实现。

class MysqlDatabase : IDatabase
{
    public DataTable ExecuteReaderCommand(MySqlCommand command)
    {
        DataTable dt = new DataTable();
        // ... read db
        return dt;
    }

    public MySqlCommand GetNewCommand()
    {
        cnn.Open();
        return cnn.CreateCommand();
    }
}

class SQLiteDatabase : IDatabase
{
String dbConnection;
    SQLiteConnection cnn;

    public DataTable ExecuteReaderCommand(SQLiteCommand command)
    {
        DataTable dt = new DataTable();
        // ... read db
        return dt;
    }

    public SQLiteCommand GetNewCommand()
    {
        cnn.Open();
        return cnn.CreateCommand();
    }
}

但是我收到错误,这些类没有实现 IDatabase 接口:

 MysqlDatabase does not implement interface member 'Database.GetNewCommand()'
 MysqlDatabase.GetNewCommand() cannot implement 'Database.GetNewCommand()' because it does not have the matching return type of 'System.Data.IDbCommand'.

 SQLiteDatabase does not implement interface member Database.ExecuteReaderCommand(System.Data.IDbCommand)
 SQLiteDatabase does not implement interface member 'Database.GetNewCommand()'. SQLiteDatabase.GetNewCommand() cannot implement Database.GetNewCommand() because it does not have the matching return type of 'System.Data.IDbCommand'.

当我查看它们时SQLiteCommandMySqlCommand它们都实现了IDbCommand.

如何在通用接口下使用这些类,以便轻松切换它们?

我非常感谢任何答案。

4

1 回答 1

4

当我查看 SQLiteCommand 和 MySqlCommand 时,它们都实现了 IDbCommand

不,他们没有。他们声称他们这样做,但他们实际上并没有提供正确的方法。看IDatabase.GetNewCommand()

IDbCommand GetNewCommand();

和你的实施:

public MySqlCommand GetNewCommand()
{
    ... 
}

他们有不同的返回类型。同样,您的ExecuteReaderCommand方法参数IDbCommand在 中IDatabase,但MySqlCommandMysqlDatabase.

选项:

  • 对“弱类型”版本使用显式接口实现,在具体类上公开“强类型”版本。例如,这就是SqlCommand在 .NET 框架中所做的。

  • 使其IDatabase创建和使用的命令类型具有通用性:

    public interface IDatabase<TCommand> where TCommand : IDbCommand
    {
        DataTable ExecuteReaderCommand(TCommand command);
        TCommand GetNewCommand();
    }
    
于 2012-07-24T17:25:08.997 回答