【问题标题】:How to make this class generic? (.NET C#)如何使这个类通用? (.NET C#)
【发布时间】:2009-01-16 13:55:11
【问题描述】:

我的班级有以下核心:

class SmartDbConnection
{
    private readonly IDbConnection Connection;

    public SmartDbConnection(string ConnectionString)
    {
        if(ConnectionString.Contains("MultipleActiveResultSets=true"))
        {
            Connection = new SqlConnection(ConnectionString);
        }
    }
}

我不希望它硬编码“SqlConnection”。所以我想把它变成一个通用类(接受 IDbConnection 类)。但我不知道该怎么做。有人可以帮忙吗?

【问题讨论】:

    标签: c# .net generics constructor interface


    【解决方案1】:

    首先 - 我已在其中添加了 IDisposable,因为我认为这很重要。

    其次,请注意提供者是这里的替代方案:

    class SmartDbConnection
    {
        private DbConnection Connection;
    
        public SmartDbConnection(string provider, string connectionString)
        {
            Connection = DbProviderFactories.GetFactory(provider)
                .CreateConnection();
            Connection.ConnectionString = connectionString;
        }
        public void Dispose() {
            if (Connection != null)
            {
                Connection.Dispose();
                Connection = null;
            }
        }
    }
    

    如果你必须通用,如何:

    class SmartDbConnection<T> : IDisposable where T : class,
        IDbConnection, new()
    {
        private T Connection;
    
        public SmartDbConnection(string connectionString)
        {
            T t = new T();
            t.ConnectionString = connectionString;
            // etc
        }
        public void Dispose() {
            if (Connection != null)
            {
                Connection.Dispose();
                Connection = null;
            }
        }
    }
    

    【讨论】:

    • provider 应该类似于“SqlConnection”
    • “where T : class, IDbConnection, new()”中的“new()”的作用是什么?
    • 这允许你在构造函数中使用 new T()
    • "System.Data.SqlClient" 用于 SQL-Server - 与配置文件中 connectionStrings 部分中的提供程序相同;如果需要,您可以通过配置添加额外的提供程序
    • 感谢您的澄清,我也收到了响应选项卡更新
    【解决方案2】:

    你为什么不接受 IDbConnection 而不是你的 ctor 的连接字符串?

    【讨论】:

    • +1:总的来说,这是一个更好、更可扩展的设计。如果您仍想为您的班级用户提供一种将连接字符串转换为 IDbConnection 的方法,请参阅 Jon Skeet 对同一问题的回答以获取技术。
    • 因为我想选择使用单个连接 if(ConnectionString.Contains("MultipleActiveResultSets=true") 或多个连接如果没有。如果我收到 IDbConnection 我不知道如何创建它的更多实例。
    【解决方案3】:

    也许……

    class SmartDbConnection<T> where T : IDbConnection, new()
    {
        private readonly IDbConnection Connection;
    
        public SmartDbConnection(string connectionString)
        {
            if (connectionString.Contains("MultipleActiveResultSets=true"))
            {
                Connection = new T();
                Connection.ConnectionString = connectionString;
            }
        }
    }
    

    编辑:但kaanbardak 的建议可能会更好......

    【讨论】:

    • 你也可以让 T 有一个接口,指定它应该能够在其构造函数中接收连接字符串。
    • @Crossbrowser:不,你不能。接口不能定义构造函数。
    • @Crossbrowser:我几乎可以肯定你不能。 ;-)
    【解决方案4】:

    如果您不想在此处指定 SqlConnection,您将在哪里指定 - 以及仅当连接字符串包含“MultipleActiveResultSets=true”时您如何知道使用它?

    我怀疑在某种程度上你想要一个连接工厂 - 要么是 Func&lt;string, IDbConnection&gt; 你可以传入或设置在某个地方,或者可能只是一个类:

    public static class ConnectionFactory
    {
        public static IDbConnection CreateConnection(string connectionString)
        {
            // Hard-code stuff here
        }
    }
    

    当然,它们只是同一枚硬币的两个方面 - ConnectionFactory 只是 Func&lt;string, IDbConnection&gt; 的静态实现。

    【讨论】:

    • 我想在调用者代码中指定SqlConnection。我不会仅在“MultipleActiveResultSets=true”时使用它,因为我的类还有其他方法(未在本文中显示)在“MultipleActiveResultSets=false”时创建多个实例
    • 如果调用者代码已经知道他们想要一个SqlConnection,为什么不把它传递给你呢?
    • 因为“他们”不知道他们想要 1 个还是多个 SqlConnections。
    • 我不确定我是否完全理解。啊,好吧-只要您对接受的答案感到满意,我是否理解都没有关系:)
    【解决方案5】:
      class SmartDbConnection<T> where T: IDbConnection , new()
      {
        private readonly T Connection;
    
        public SmartDbConnection(string ConnectionString)
        {
          if (ConnectionString.Contains("MultipleActiveResultSets=true"))
          {
            Connection = new T();
            Connection.ConnectionString = ConnectionString;
          }
        }
      }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      相关资源
      最近更新 更多