【问题标题】:Generic Class VB.NET泛型类 VB.NET
【发布时间】:2011-02-26 07:47:35
【问题描述】:

我遇到了一个关于泛型类的问题。我很困惑如何使用参数调用构造函数。

我的界面:

Public Interface IDBObject
    Sub [Get](ByRef DataRow As DataRow)
    Property UIN() As Integer
End Interface

我的孩子班:

Public Class User
    Implements IDBObject

    Public Sub [Get](ByRef DataRow As System.Data.DataRow) Implements IDBObject.Get

    End Sub

    Public Property UIN() As Integer Implements IDBObject.UIN
        Get

        End Get
        Set(ByVal value As Integer)

        End Set
    End Property
End Class

我的下一堂课:

Public Class Users
    Inherits DBLayer(Of User)

#Region " Standard Methods "

#End Region
End Class

我的 DBObject 类:

Public Class DBLayer(Of DBObject As {New, IDBObject})

    Public Shared Function GetData() As List(Of DBObject)
        Dim QueryString As String = "SELECT * ***;"
        Dim Dataset As DataSet = New DataSet()
        Dim DataList As List(Of DBObject) = New List(Of DBObject)

        Try
            Dataset = Query(QueryString)
            For Each DataRow As DataRow In Dataset.Tables(0).Rows
                **DataList.Add(New DBObject(DataRow))**
            Next
        Catch ex As Exception
            DataList = Nothing
        End Try
        Return DataList
    End Function
End Class

我在 DBLayer 对象的星标区域出现错误。

可能的原因是什么?我该怎么做才能解决它?

我什至想在 IDBObject 接口中添加 New(byval someval as datatype) 用于重载构造。但它也给出了一个错误?我该怎么做?

添加

IDBObject 中的 Sub New(ByVal DataRow As DataRow) 产生以下错误 不能在接口中声明“Sub New”。

DBLayer 对象中产生的错误 行:DataList.Add(新 DBObject(DataRow)) 消息:参数不能传递给类型参数上使用的“新”。

【问题讨论】:

    标签: vb.net generics class inheritance interface


    【解决方案1】:

    对于构造函数,那是因为你不能在接口中定义构造函数。

    编辑:

    我明白你现在想要做什么。您想创建一个定义 DBLayer 的泛型类型的新实例。您的问题将是您无法指定接口的实现需要具有特定的构造函数。您可能最好在您的接口上有一个接受 DataRow 并使用它来初始化 IDBObject 的方法,然后您可以创建一个 DBObject 类型的实例,然后调用接受 DataRow 的方法来初始化您的实例。

    或者您可以要求您的 DBLayer 类采用一个工厂类,该工厂类可以在给定 DataRow 的情况下生成 DBObject 类型的对象,并且您可以调用工厂的这个方法来代替调用

            For Each rowAs DataRow In Dataset.Tables(0).Rows
                //DataList.Add(New DBObject(row))
                DataList.Add(m_factory.CreateObject(row));
            Next
    

    编辑 2:

    最简单的方法是扩展你的接口,允许你设置 DataRow 并在循环中调用方法:

            For Each row As DataRow In Dataset.Tables(0).Rows
                //DataList.Add(New DBObject(row))
                Dim newElement As IDBObject = CType(Activator.CreateInstance(GetType(DBObject)), IDBObject)
                //you'll need to add this SetDataRow method the the IDBObject interface
                newElement.SetDataRow(row)
                DataList.Add(newElement)
            Next
    

    【讨论】:

    • 所以如果我想做一些类似的事情可以做什么 DataList.Add(New DBObject(DataRow)) 选择不同的名称也不能解决这个问题
    • 对 m)factory 或类工厂感到困惑...我不是太高级的程序员...需要一些更基本的概念...你能详细说明一下吗
    • 按照你所说的尝试过,但它仍然显示一些错误,例如:“Option Strict On 不允许从 'IDBObject' 到 'DBObject' 的隐式转换”。我在 IDBObject 中为 setDataRow(byval DataRow as DataRow) 添加了一个新子
    • 尝试使用CType 而不是DirectCast
    • 或在代码顶部关闭 option strict 以查看它是否有效。我的 VB 不是很好,对不起。
    【解决方案2】:

    如果您使用抽象类而不是接口 IDBObject 会怎样?然后你应该继承而不是实现。 抽象类可以定义所需的构造函数。

    【讨论】:

    • 在我们做泛型的时候可以使用抽象类吗...任何帖子或代码示例?
    • 您可以使用抽象类代替接口(在 Vb.Net 中,关键字是 MustInherit)。定义泛型类时,您只需将类型限制为基类型。这里的接口和抽象类一样。
    • 虽然这个想法没问题,但不能保证实现类会包含你想要的构造函数,它可能会向构造函数添加额外的参数,所以你将无法调用构造函数DataRow 确信它不会失败。您唯一可以保证的是,使用New 约束默认构造函数将存在的类型。
    【解决方案3】:

    问题在于 New 约束。它只承诺一个无参数构造函数,编译器无法推断 DbObject 类型参数可能有一个以 DataRow 作为参数的构造函数。

    您也许可以使用获取/设置 DataRow 的属性来扩展 IDbObject 接口。类工厂会很有帮助。

    【讨论】:

      【解决方案4】:

      它不像对您所指的内容感到困惑那么简单?您有“For Each DataRow As DataRow”这一行,这似乎是造成混淆的秘诀,可能是当您在构造函数中引用 DataRow 时,它没有使用循环变量,而是使用数据类型“DataRow”。即使这不是问题,您也可能希望将循环变量更改为不那么模棱两可的变量。

      你得到的实际错误是什么?

      此外,对于添加额外构造函数的最后一部分,您会遇到什么错误?如果您要向接口添加一些东西,您是否将额外的构造函数添加到实现该接口的所有东西?

      【讨论】:

      • 不是循环错误...我添加了正在产生的错误
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-07-21
      • 1970-01-01
      • 1970-01-01
      • 2010-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多