类型约束可以是独占的而不是包容的吗?

时间:2014-06-20 21:01:31

标签: .net vb.net generics type-constraints

我正在研究一个与VB.NET和多个通用接口相关的奇怪问题。我通过指定两个不同的泛型类型参数,实现了两次泛型接口。为了找到这个问题的解决方案(如下所列),我有了一个想法,但无法找到任何资源来确定这是否可行。

VB.NET Implement Mutliple Contravariant interface types

此处的MSDN文档:http://msdn.microsoft.com/en-us/library/d5x73970.aspx解释了类型约束用法,这有用但不完整(或者至少语言不支持我想要的内容)。

通常,约束声明为:

Public Interface ICopiesFrom(Of TObject As Class)
    Sub CopyFrom(ByVal data As TObject)
End Interface

但是我想说我想排除一个可能的泛型类型参数,而不是限制为子集。

Public Sub Interface ICopiesFrom(Of TObject Not As SpecificBadType)

可以这样做吗?

看起来似乎:How to call a generic method with type constraints when the parameter doesn't have these constraints?是重复的,但我的问题有点不同,因为我喜欢编译时的支持。

修改

这是一个示例用例(可能是这样的):

'Ideally, the interface would have a definition like this
Public Interface ICopiesFrom(Of TModel As Not ISecureType)
    Sub CopyFrom(ByVal data As TModel)
End Interface

'Target type to exclude
Public Interface ISecureType

    Property AccountValue As Decimal
    Property AccountNumber As String

End Interface

Public Class AccountModel

    Public Overridable Property AccountCreated As DateTime
    Public Overridable Property ReferredBy As Guid

End Class

Public Class DetailedAccountModel
    Inherits AccountModel
    Implements ISecureType

    Public Property AccountNumber As String Implements ISecureType.AccountNumber
    Public Property AccountValue As Decimal Implements ISecureType.AccountValue

End Class

Public Class ProfileModel

    Public Property UserName As String
    Public Property EmailAddress As String
    Public Property PhoneNumber As String

End Class

Public Class User 'Composite representation for a view
    Implements ICopiesFrom(Of ProfileModel)
    Implements ICopiesFrom(Of AccountModel)

    Public Property UserName As String
    Public Property EmailAddress As String
    Public Property PhoneNumber As String
    Public Property AccountCreated As DateTime
    Public Property ReferredBy As Guid

    Public Overridable Overloads Sub CopyFrom(ByVal data As ProfileModel) Implements ICopiesFrom(Of ProfileModel).CopyFrom
        If data IsNot Nothing Then
            Me.UserName = data.UserName
            Me.EmailAddress = data.EmailAddress
            Me.PhoneNumber = data.PhoneNumber
        End If
    End Sub

    Public Overridable Overloads Sub CopyFrom(ByVal data As AccountModel) Implements ICopiesFrom(Of AccountModel).CopyFrom
        If data IsNot Nothing Then
            Me.AccountCreated = data.AccountCreated
            Me.ReferredBy = data.ReferredBy
        End If
    End Sub

    Public Function AccountAge() As Double
        Return (DateTime.Now - AccountCreated).TotalDays
    End Function

End Class

在上面的场景中,我绝不希望有人能够将DetailedAccountModel传递到User课程,以便它永远不会意外地#34;显示,理想情况下,这将在编译时捕获。

以下任何一种都是可接受的答案:

  • 一种完全实现此目的的方法
  • 实现相同结果(或类似)的替代方法
  • 确认我疯了,但这不能做(当然有消息来源)。

1 个答案:

答案 0 :(得分:1)

不,没有办法做到这一点。您可以ask for it to be considered作为语言功能,但我认为语言创建者认为这会鼓励人们编写违反开放/封闭原则的代码。

例如,您现在可能知道某个特定类不应该用作泛型类型,但是阻止其他人提出您的其他类型的内容是什么?现在不了解。您尝试排除特定类型的事实是代码气味,这可能表明还有另一种更好的方法来解决您尝试解决的问题。也许您在使用组合时使用继承。也许您可以通过隔离接口或使用更好的关注点来获益。也许通过不包括此功能,该语言实际上帮助我们编写更易于维护的代码。