I want to do some arithmetic addition in my generic class with some constraints in place. For brevity, assume there is just one public member named Value
.
Public MustInherit Class GenericInterval(Of T As {Structure, IComparable})
Public Value As T
'(1) filled in below
End Class
Outside the class, I have an interface and a structure implementing it as follows:
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
This enables me to create a function in my class at position marked (1) above. There are some constraints, but as far as I can tell, I think I got that part right. New
on C
is needed, otherwise As C = New C()
would not be possible.
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
Now I intended to use this function to do calculations in the class' overridden GetHashCode
function, as follows:
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
However, VS complains with error BC32044, the squiggly underlines referring to
Add(Of T, Int64Calculator)
stating
"Type argument 'Int64Calculator' does not inherit from or implement the constraint type 'IAddable(Of T As {Structure, IComparable})'".
Only that I think that the structure Int64Calculator
does implement that constraint indeed via Implements IAddable(Of Int64)
.
What do I miss?
Part 1:
As @Gserg commented:
GenericInterval
does not enforce T to be Int64
. So at the point when Int64Calculator
is tested for validity, it is required to handle any T as {Structure, IComparable}
, not just Int64
. You can fix that with lCompHash = Me.Add(Of Int64, Int64Calculator)(Me.Value, HASHPRIME_1)
, but then you'll have another error about Me.Value not necessarily being convertable to Int64
.
Part 2:
This simplest way to implement GetHashCode for the case where you consider objects as equal based on certain properties is to use Tuple.Create(x,y).GetHashCode()
For example, if you consider properties equal that have the same Name
and PhoneNumber
properties, then the following code would return a usable HashCode.
public override int GetHashCode() { return Tuple.Create(Name, PhoneNumber).GetHashCode(); }