1

This shouldnt be hard to answer but I am so desperate and confused. I made interface for executing read query from database

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

Next, I created two different classes implemetnig above interface.

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

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

And

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();
    }
}

But I am getting error that these classes dont implement IDatabase interface:

 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'.

When I look on the SQLiteCommand and MySqlCommand they both implements IDbCommand.

How can I use these classes under common interface so I can easilly switch them?

I am very thankful for any answer.

1 Answer 1

4

When I look on the SQLiteCommand and MySqlCommand they both implements IDbCommand

No they don't. They claim they do, but they don't actually provide the right methods. Look at IDatabase.GetNewCommand():

IDbCommand GetNewCommand();

and your implementation:

public MySqlCommand GetNewCommand()
{
    ... 
}

They've got different return types. Likewise your ExecuteReaderCommand method parameter is IDbCommand in IDatabase, but MySqlCommand in MysqlDatabase.

Options:

  • Use explicit interface implementation for the "weakly typed" version, exposing the "strongly typed" versions on the concrete classes. This is what SqlCommand does in the .NET framework, for example.

  • Make IDatabase generic in the type of command it creates and uses:

    public interface IDatabase<TCommand> where TCommand : IDbCommand
    {
        DataTable ExecuteReaderCommand(TCommand command);
        TCommand GetNewCommand();
    }
    
Sign up to request clarification or add additional context in comments.

1 Comment

Option 1 is exactly what I wanted to do. Could you please point me in right direction how to do it? I need common interface for MysqLCommand and SQLiteCommand. I thought it is IDbCommand.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.