定义多种T类型是Generic Overkill吗?

时间:2011-05-25 15:48:04

标签: c# vb.net generics

注意:我正在混合使用VB和C# - 来自不同库的片段

我有一个VB类定义如下:

Public Class Session(Of TConnectionBuilder As {DbConnectionStringBuilder, New}, _
                         TConnection As {DbConnection, New}, _
                         TDataReader As {DbDataReader})

我想知道这是不是太通用了?可能有更好的解决方案......

Session负责处理所需的一组类:创建连接字符串,实例连接和返回数据引导器。实例化会话需要以下内容:

session = new Session<SqlConnectionStringBuilder, SqlConnection, SqlDataReader>(@"serverName", "dbName");

会话的构造函数:

Private dataReader As DataReader(Of TConnection, TDataReader)
Private ReadOnly settings As TConnectionBuilder

//   assume integrated security
Public Sub New(ByVal Server As String, ByVal Database As String)
    settings = New TConnectionBuilder()
    settings.Add("Server", Server)
    settings.Add("Database", Database)
    settings.Add("integrated security", True)

    dataReader = New DataReader(Of TConnection, TDataReader)(settings)
End Sub

Public Sub New(ByVal Server As String, ByVal Database As String, ByVal UserID As String, ByVal Password As String)
    settings = New TConnectionBuilder()
    settings.Add("Server", Server)
    settings.Add("Database", Database)
    settings.Add("UserID", UserID)
    settings.Add("Password", Password)

    dataReader = New DataReader(Of TConnection, TDataReader)(settings)
End Sub

DataReader是一个自定义泛型类:

Friend Class DataReader(Of TConnection As {DbConnection, New}, _
                            TDataReader As {DbDataReader})

那么,这没关系吗?是否有更多可接受的解决方案?唯一感觉“笨拙”的是实例化初始会话对象。

3 个答案:

答案 0 :(得分:2)

 > Is it Generic Overkill to define multiple T types?

一般来说,它不像Dictionary<TKey, TValue>中显示的那样。

在您的示例中,您需要泛型的唯一原因是您希望使用new运算符创建特殊类型的对象。其他所有操作都可以通过使用基本类型DbXxx而不是通用TXxx来完成。

在你的例子中,我会使用工厂而不是使用泛型。对于databaseworld,microsoft有一个buildin System.Data.Common.DbProviderFactoryDbProviderFactories已经提供了最需要的功能。

然而编写可移植代码非常困难。例如,您的示例包含

settings.Add("integrated security", True) 

只适用于mssql

答案 1 :(得分:1)

不是真的 - 这取决于具体情况。你已经使用了约束...所以它像你可以撞到任何东西。它是通用的,但对于一组特定的类,这很好。类定义告诉了我很多关于会话将要使用的内容。

如果你想要编译时检查,那么这是有道理的。

泛型的唯一问题是它们可能有点头疼......直到你习惯了它们。另一种方法是使用对象和转换。我更喜欢尽可能在编译时失败,因为那时我必须测试更少(或者说编译器可以做到这一点)。

如果您想要一个独立于其类型的“会话”对象集合,您可能会发现您遇到了问题。

我不认为这有什么不妥。这意味着您可以独立于约束的所有实现来测试此类。这很有意义,也很整洁。

TBH id可能会考虑使其更通用,并使用约束类的接口...(例如IDBReader和IDBConnection)。

你可以通过构成btw获得类似的结果 - id需要知道你想要做什么来找出在这种情况下最好的。

答案 2 :(得分:1)

您应该使用DbProviderFactory Class

结帐Jean-Paul Boodhoo on Demystifying Design Patterns Part 5 - dnrTV 这证明了用法。

是的,在这种情况下,这是泛型的过度使用。