调用通用函数(使用接口实现约束)会产生有关缺少约束的错误。我看不到什么?
A call to a generic function (with constraints implemented with an interface) produces an error about missing constraints. What do I fail to see?
我想在我的泛型 class 中做一些算术加法,但有一些限制。为简洁起见,假设只有一个名为 Value
.
的 public 成员
Public MustInherit Class GenericInterval(Of T As {Structure, IComparable})
Public Value As T
'(1) filled in below
End Class
在class之外,我有一个接口和实现它的结构如下:
Public Interface IAddable(Of U As {Structure, IComparable})
Function Add(a As U, b As U) As U
End Interface
Public Structure Int64Calculator
Implements IAddable(Of Int64)
Public Function Add(ByVal a As Int64, ByVal b As Int64) As Int64 _
Implements IAddable(Of Int64).Add
Return a + b
End Function
End Structure
这使我能够在上面标记 (1) 的位置的 class 中创建一个函数。有一些限制,但据我所知,我认为我做对了。 New
on C
是必需的,否则 As C = New C()
是不可能的。
Public MustInherit Class GenericInterval(Of T As {Structure, IComparable})
Public Value As T
'(2) filled in below
Private Function Add(Of U As {Structure, IComparable},
C As {IAddable(Of U), New}) _
(ByVal a As U, ByVal b As U) As U
Dim calc As C = New C()
Return calc.Add(a, b)
End Function
End Class
现在我打算用这个函数在class'重写的GetHashCode
函数中做计算,如下:
Public MustInherit Class GenericInterval(Of T As {Structure, IComparable})
Public Value As T
Public Overrides Function GetHashCode() As Integer
Const HASHPRIME_1 As Int64 = 4294967291 '32 bits.
Dim lCompHash As Int64 'Partial hash for actual component.
lCompHash = Add(Of T, Int64Calculator)(Value, HASHPRIME_1)
End Function
'... as above
End Class
但是,VS 报错 BC32044,波浪下划线指的是
Add(Of T, Int64Calculator)
说
"Type argument 'Int64Calculator' does not inherit from or implement
the constraint type 'IAddable(Of T As {Structure, IComparable})'".
只是我认为结构 Int64Calculator
确实通过 Implements IAddable(Of Int64)
.
实现了该约束
我错过了什么?
第 1 部分:
正如@Gserg 评论的那样:
GenericInterval
不强制 T 为 Int64
。所以在测试Int64Calculator
有效性的时候,需要把任何T都当作{Structure, IComparable}
来处理,而不仅仅是Int64
。您可以使用 lCompHash = Me.Add(Of Int64, Int64Calculator)(Me.Value, HASHPRIME_1)
修复该问题,但随后您会遇到另一个关于 Me.Value 不一定可转换为 Int64
.
的错误
第 2 部分:
对于基于某些属性认为对象相等的情况,实现 GetHashCode 的最简单方法是使用 Tuple.Create(x,y).GetHashCode()
例如,如果您认为具有相同 Name
和 PhoneNumber
属性的属性相等,则以下代码将 return 一个可用的 HashCode。
public override int GetHashCode() { return Tuple.Create(Name, PhoneNumber).GetHashCode(); }
我想在我的泛型 class 中做一些算术加法,但有一些限制。为简洁起见,假设只有一个名为 Value
.
Public MustInherit Class GenericInterval(Of T As {Structure, IComparable})
Public Value As T
'(1) filled in below
End Class
在class之外,我有一个接口和实现它的结构如下:
Public Interface IAddable(Of U As {Structure, IComparable})
Function Add(a As U, b As U) As U
End Interface
Public Structure Int64Calculator
Implements IAddable(Of Int64)
Public Function Add(ByVal a As Int64, ByVal b As Int64) As Int64 _
Implements IAddable(Of Int64).Add
Return a + b
End Function
End Structure
这使我能够在上面标记 (1) 的位置的 class 中创建一个函数。有一些限制,但据我所知,我认为我做对了。 New
on C
是必需的,否则 As C = New C()
是不可能的。
Public MustInherit Class GenericInterval(Of T As {Structure, IComparable})
Public Value As T
'(2) filled in below
Private Function Add(Of U As {Structure, IComparable},
C As {IAddable(Of U), New}) _
(ByVal a As U, ByVal b As U) As U
Dim calc As C = New C()
Return calc.Add(a, b)
End Function
End Class
现在我打算用这个函数在class'重写的GetHashCode
函数中做计算,如下:
Public MustInherit Class GenericInterval(Of T As {Structure, IComparable})
Public Value As T
Public Overrides Function GetHashCode() As Integer
Const HASHPRIME_1 As Int64 = 4294967291 '32 bits.
Dim lCompHash As Int64 'Partial hash for actual component.
lCompHash = Add(Of T, Int64Calculator)(Value, HASHPRIME_1)
End Function
'... as above
End Class
但是,VS 报错 BC32044,波浪下划线指的是
Add(Of T, Int64Calculator)
说
"Type argument 'Int64Calculator' does not inherit from or implement the constraint type 'IAddable(Of T As {Structure, IComparable})'".
只是我认为结构 Int64Calculator
确实通过 Implements IAddable(Of Int64)
.
我错过了什么?
第 1 部分:
正如@Gserg 评论的那样:
GenericInterval
不强制 T 为 Int64
。所以在测试Int64Calculator
有效性的时候,需要把任何T都当作{Structure, IComparable}
来处理,而不仅仅是Int64
。您可以使用 lCompHash = Me.Add(Of Int64, Int64Calculator)(Me.Value, HASHPRIME_1)
修复该问题,但随后您会遇到另一个关于 Me.Value 不一定可转换为 Int64
.
第 2 部分:
对于基于某些属性认为对象相等的情况,实现 GetHashCode 的最简单方法是使用 Tuple.Create(x,y).GetHashCode()
例如,如果您认为具有相同 Name
和 PhoneNumber
属性的属性相等,则以下代码将 return 一个可用的 HashCode。
public override int GetHashCode() { return Tuple.Create(Name, PhoneNumber).GetHashCode(); }