【问题标题】:Type argument does not inherit from or implement the constraint type error类型参数不继承或实现约束类型错误
【发布时间】:2019-10-02 23:12:19
【问题描述】:

我正在尝试使用通用类型创建通用运动类。我的顶级对象是包含 Teams 和 Players 对象的 Sport:

体育课

Public Class Sport(Of TTeams As {Teams(Of Team(Of Players(Of Player))), New}, TPlayers As {Players(Of Player), New})
    Public Teams As New TTeams
    Public Players As New TPlayers
End Class

TeamsPlayers 也是通用的:

团队和团队类

Public Class Teams(Of TTeam As {Team(Of Players(Of Player)), New})

    Protected _teams As List(Of TTeam)

    Sub New()
        _teams = New List(Of TTeam)
    End Sub

    Public Function GetByCity(city As String) As TTeam
        Dim team As TTeam = _teams.Find(Function(t As TTeam) t.City = city)

        If team Is Nothing Then
            ' Create team
            team = New TTeam
            team.City = city
            _teams.Add(team)
        End If

        Return team

    End Function

End Class

Public Class Team(Of TPlayers As Players(Of Player))
    Public Property City As String
    Protected _players As TPlayers
End Class

团队包含一部分玩家 (_players)。为了简单起见,代码并不完整。

播放器和播放器类

Public Class Players(Of TPlayer As {Player, New})

    Protected _players As List(Of TPlayer)

    Sub New()
        _players = New List(Of TPlayer)
    End Sub

    Public Function GetByName(name As String) As TPlayer
        Dim player As TPlayer = _players.Find(Function(p As TPlayer) p.Name = name)

        If player Is Nothing Then
            ' Create player
            player = New TPlayer
            player.Name = name
            _players.Add(player)
        End If

        Return player

    End Function

End Class

Public Class Player
    Public Property Name As String
    Public Property Number As Integer
End Class

到目前为止,所有这一切似乎都很好。下一步是当我尝试将这些用于特定运动时,事情变得令人困惑:

棒球实施

Public Class Baseball
    Inherits Sport(Of BaseballTeams, BaseballPlayers)
End Class

Public Class BaseballTeam
    Inherits Team(Of BaseballPlayers)

    Public Property League As String
    Public Property Division As String

End Class

Public Class BaseballTeams
    Inherits Teams(Of BaseballTeam)

    Public Function GetLeagueTeams(ByVal league As String) As List(Of BaseballTeam)
        Return _teams.FindAll(Function(t As BaseballTeam) t.League = league)
    End Function

End Class

Public Class BaseballPlayer
    Inherits Player

    Public Property BattingAverage As Single

End Class

Public Class BaseballPlayers
    Inherits Players(Of BaseballPlayer)

End Class

我收到 4 个错误 (BC32044):

  1. 对于Baseball类:

类型参数“BaseballTeams”不继承或实现 约束类型'Teams(Of Team(Of Players(Of Player)))'

  1. 对于Baseball类:

类型参数“BaseballPlayers”不继承或实现 约束类型'Players(Of Player)'

  1. 对于BaseballTeam类:

类型参数“BaseballPlayers”不继承或实现 约束类型'Players(Of Player)'。

  1. 对于BaseballTeams类:

类型参数“BaseballTeam”不继承或实现 约束类型'Team(Of Players(Of Player))'

我不明白实施有什么问题。任何帮助将不胜感激!感谢您阅读我的问题。


编辑 1:我尝试将所有类型直接传递到 Sport 类定义中:

Public Class Sport(Of TTeams As {Teams(Of TTeam, TPlayers), New}, TTeam As Team(Of TPlayers), TPlayers As {Players(Of TPlayer), New}, TPlayer As {Player, New})
    Public Teams As New TTeams
    Public Players As New TPlayers
End Class

还有这个:

Public Class Teams(Of TTeam As {Team(Of TPlayers), New}, TPlayers As Players(Of TPlayer), TPlayer As Player)

我希望通过在声明本身中定义类型来简化声明。这并没有让我更进一步,只是给出了更多错误。

【问题讨论】:

  • 这太可怕了。没有人能够有效地维持这种意大利面混乱。我强烈建议您重新考虑您的继承架构。
  • 确实如此,我正在努力寻找更好的方法。我觉得如何将一项运动分解为团队和球员的架构是合理的,但对于我正在尝试的通用类型,它会变得非常丑陋。除了指出显而易见的问题(这是一团糟)之外的任何帮助将不胜感激。
  • Inherits Sport(Of BaseballTeams, BaseballPlayers) 但是 BaseballTeams 已经从一个 Team(of BaseballPlayers) 继承。是的,非常混乱。我会放弃泛型。只需使用接口来定义棒球队和足球队等将实现的通用属性等。
  • @LarsTech 尽管此处显示的通用类中的代码不多,但它们将包含所有运动队和球员共享的大量代码。有了接口,我就不必为每项运动复制相同的代码了吗?
  • 基类或抽象类也可以。您的泛型使一切变得非常复杂并且并不真正适用,因为您想要一些非常具体而不是非常通用的东西。

标签: vb.net generics


【解决方案1】:

设法通过将TPlayerTTeam 传递到链中来使其工作。仍然有点难以阅读,但它有效:

运动

Public Class Sport(Of TPlayer As {Player, New}, TTeam As {Team(Of TPlayer), New})

    Public Teams As New Teams(Of TPlayer, TTeam)
    Public Players As New Players(Of TPlayer)

End Class

团队和团队

Public Class Teams(Of TPlayer As {Player, New}, TTeam As {Team(Of TPlayer), New})

    Protected _teams As List(Of TTeam)

    Sub New()
        _teams = New List(Of TTeam)
    End Sub

    Public Function GetByCity(city As String) As TTeam

        Dim team As TTeam = _teams.Find(Function(t As TTeam) t.City = city)

        If team Is Nothing Then
            ' Create team
            team = New TTeam
            team.City = city
            _teams.Add(team)
        End If

        Return team

    End Function

End Class

Public Class Team(Of TPlayer As {Player, New})

    Public Property City As String
    Public Players As New Players(Of TPlayer)

End Class

玩家和玩家

Public Class Players(Of TPlayer As {Player, New})

    Protected _players As New List(Of TPlayer)

    Sub New()
        _players = New List(Of TPlayer)
    End Sub

    Public Function GetByName(name As String) As TPlayer
        Dim player As TPlayer = _players.Find(Function(p As TPlayer) p.Name = name)

        If player Is Nothing Then
            ' Create player
            player = New TPlayer
            player.Name = name
            _players.Add(player)
        End If

        Return player

    End Function

End Class

Public Class Player

    Public Property Name As String
    Public Property Number As Integer

End Class

最后是棒球的实现和测试代码:

棒球实施

Public Class Baseball
    Inherits Sport(Of BaseballPlayer, BaseballTeam)
End Class

Public Class BaseballTeams
    Inherits Teams(Of BaseballPlayer, BaseballTeam)

    Public Function GetLeagueTeams(ByVal league As String) As List(Of BaseballTeam)
        Return _teams.FindAll(Function(t As BaseballTeam) t.League = league)
    End Function

End Class
Public Class BaseballTeam
    Inherits Team(Of BaseballPlayer)

    Public Property League As String
    Public Property Division As String

End Class

Public Class BaseballPlayers
    Inherits Players(Of BaseballPlayer)

End Class

Public Class BaseballPlayer
    Inherits Player

    Public Property BattingAverage As Single

End Class

测试

Private Sub Test()
    Dim league As New Baseball
    Dim team As BaseballTeam
    Dim player As BaseballPlayer

    team = league.Teams.GetByCity("Los Angeles")
    player = team.Players.GetByName("Ohtani")

    player.BattingAverage = 0.286
    player.Number = 17

    MsgBox(player.Name & " #" & player.Number & " (" & team.City & "): " & player.BattingAverage)

End Sub

感谢您阅读此问题和答案。尽管它看起来很可怕,但它确实有效,我希望这段代码可以帮助其他人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-28
    相关资源
    最近更新 更多