如何正确连接现有的密封类?

时间:2014-10-03 07:47:20

标签: c# inheritance

在CodeReview上审查我的代码后,我仍然坚持如何使我的代码更抽象的问题。

正如您在here中所看到的,很多人建议我应该创建一个ICommandIConnection界面,以便更容易重构。

在我的示例中,我只会使用IConnection,但整体也应该对ICommand有效。

我想我必须创建一个像这样的界面;

public interface IConnection
{
     //etc...
}

然后,为了让MySqlConnection能够从我的IConnection继承,我必须创建我自己的MySqlConnection,这将继承这样;

public class MySqlConnection : MySql.Data.MySqlClient.MySqlConnection, IConnection
{
     //etc...
}

这意味着新的MySqlConnection仍有其方法和字段,将继承自IConnection。然后我应该能够像这样写一个Database类;

public abstract class Database
{
    protected IConnection con;
}

并像这样扩展它;

public class MySqlDatabase : Database
{
    private override IConnection con = new MySqlConnection();
}

现在,我的问题是,MySqlConnectionsealed;我无法扩展它,因此我不知道任何使这个数据库类抽象的选项。

问题是;是否有适当的方法来实现Database的抽象,如果是,我该怎么做?

请注意这个问题与作为单身人士的班级无关(如我的CodeReview帖子所示)。该问题已经发布,与该问题无关。

2 个答案:

答案 0 :(得分:4)

阅读有关该代码审核的评论,我实际上认为它们意味着使用IDbConnectionIDbCommand而不是滚动自己。所有ADO.NET提供商都已经实现了这些。

但是,如果您愿意,可以继承DbConnectionIConnection以及换行 MySqlConnection。您必须实现所有DbConnection方法并将它们转发到包装连接:

public sealed class MyMySqlConnection : DbConnection, IConnection
{
    public MyMySqlConnection(MySqlConnection underlyingConnection)
    {
        UnderlyingConnection = underlyingConnection;
    }

    public MySqlConnection UnderlyingConnection
    {
        get;
        private set;
    }

    public override void Open()
    {
        UnderlyingConnection.Open();
    }

    // ...

答案 1 :(得分:0)

如何实施decorator模式:

interface IConnection
{
    string ConnectionString {get; set;} // Define your interface explicitly
}

然后你可以创建一个这样的类:

class MySqlDbConnection : IConnection
{
    private MySql.Data.MySqlClient.MySqlConnection connection;

    public MySqlConnection(MySql.Data.MySqlClient.MySqlConnection connection)
    {
        // Check for null
        this.connection = connection;
    }

    #region Implementation of IConnection
    public ConnectionString
    {
        get
        {
            return connection.ConnectionString; // Not sure if this is the right name of property
        }
        set
        {
            connection.ConnectionString = value;
        }
    }
    #endregion
}

那你怎么做到这一点:

1)您可以显式公开您真正需要的Connection类的那些字段

2)您仍然可以在具体Database

的初始化阶段进行初始配置

3)你的代码变得某种更抽象的

4)并且非常方便 - 如果不同数据库(fe mysql / sqlite等)的连接将具有不同的connectionString字段名称 - 那么您可以用您的单个属性包装它们,由您定义接口。我的意思是 - 你是统治这种情况的人,在这一点上,继承可能会限制你。

无论如何,在开始实现某些东西之前,尝试用接口描述所有内容,然后才实现类。