c# - 重构以使用具有不同输入对象的通用函数

标签 c# generics dynamictype

我想重构一些在控制台应用程序中运行的代码。该应用程序更新了一个外部数据库,最近更新为支持 MySQL 或 SQL Server。所以现在有两个几乎相同的方法,其中有很多重复代码,因为一个方法签名使用 MySqlConnection 和 MySqlCommand(等),另一个使用 SqlConnection 和 SqlCommand(等)。

除了 ADO 对象中的明显差异外,代码基本相同。

我想做的是类似下面的事情。我在这里看到了几篇关于 SO 的帖子(例如 How do I use reflection to call a generic method? )以及其他展示如何使用动态类型进行设置的网站,这很棒,除了没有一个例子比写 foo 做更多的事情。泛型方法中的 GetType() 来证明动态类型是正确的。

那么,如何调用该动态类型的方法呢?当然,当我尝试设置它时,尝试调用 sqlConnection 参数上的 Open() 方法不会编译。

这是我想要完成的事情:

private static void TransferXmlData(ExportManifest m_settings, XmlNodeList xmlNodeList)
{
    if (m_Settings.ServerType.ToLower() == "mysql")
    {
        using (MySqlConnection mySqlConnection = new MySqlConnection(m_Settings.TargetData.ConnectionString))
        {
            MySqlCommand mySqlCommand = 
                new MySqlCommand(Program.GetCommandTextTemplate(m_settings), mySqlConnection);
            PrepareSqlCommand(mySqlConnection, mySqlCommand, m_settings)
        }
    }
    else
    {
        using (SqlConnection sqlConnection = 
            new SqlConnection(m_Settings.TargetData.ConnectionString))
        {
            SqlCommand sqlCommand = 
                new SqlCommand(Program.GetCommandTextTemplate(m_settings), sqlConnection);
            PrepareSqlCommand(sqlConnection, sqlCommand, m_settings)
        }
    }
}

private static void PrepareSqlCommand<T>(T sqlConnection, T sqlCommand, ExportManifest m_settings)
{
    // Potentially a lot of code here that looks just like the 
    // code in the else block, Except that it uses the 
    // MySqlConnection objects instead of SqlConnection
    // Do some stuff
    sqlConnection.Open();  // obviously doesn't work
}

提前致谢!

最佳答案

也许你可以实现工厂设计模式(如果你不想使用泛型,这是我的意见你可以考虑一下。) 这将帮助您防止代码重复。

实现您的工厂类。

`

Public class Factory
    {
        public static IDbConnection createDbInstance(ExportManifest m_settings)
        {
            if (m_Settings.ServerType.ToLower() == "mysql")
            {
                 return new MySqlConnection();

            }

            else
               return new SqlConnection();
        }
    } `

在您的实际方法中,您可以使用 IDbConnection 和 IDbCommand

private static void TransferXmlData(ExportManifest m_settings, XmlNodeList xmlNodeList)
{
    IDbConnection db = Factory.createDbInstance(m_settings);
                db.ConnectionString = m_Settings.TargetData.ConnectionString;
                IDbCommand comnd = db.CreateCommand();

                comnd.CommandText = Program.GetCommandTextTemplate(m_settings);
                comnd.CommandType = CommandType.Text;
               // db.Open(); if you want to open connection here
                PrepareSqlCommand(db, comnd, m_settings);

private static void PrepareSqlCommand(IDbConnection sqlConnection, IDbCommand sqlCommand, ExportManifest m_settings)
{
    // Potentially a lot of code here that looks just like the 
    // code in the else block, Except that it uses the 
    // MySqlConnection objects instead of SqlConnection
    // Do some stuff
    sqlConnection.Open(); 
}

关于c# - 重构以使用具有不同输入对象的通用函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40187077/

相关文章:

swift - 可选链的动态类型与赋值不同

c# - 如何确定文化的货币符号位置

c# - 将 View 模型中的 ObservableCollection 绑定(bind)到列表框

c# - 的含义是什么?运算符(operator)?

Java 泛型 - 不在界限之内

ios - Swift 反射 - 如何检查反射值是否是一种类型

c# - 防止对象在拖动开始时跳到中心点

generics - 为什么 Dart 泛型类不能根据构造函数确定其类型

.net - 在对象列表中搜索所有属性

ios - 动态类型和 iOS 模拟器 : How can I set the value?