Вызов универсальной функции (с ограничениями, реализованными с помощью интерфейса) выдает ошибку о пропущенных ограничениях. Что я не вижу? - PullRequest
3 голосов
/ 17 апреля 2019

Я хочу сделать некоторое арифметическое добавление в моем родовом классе с некоторыми ограничениями. Для краткости предположим, что существует только один публичный член с именем Value.

Public MustInherit Class GenericInterval(Of T As {Structure, IComparable})
    Public Value As T

    '(1) filled in below
End 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) выше. Есть некоторые ограничения, но, насколько я могу судить, я думаю, что правильно понял эту часть. New на 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

Теперь я намеревался использовать эту функцию для выполнения вычислений в переопределенной функции класса 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)

с указанием

"Аргумент типа 'Int64Calculator' не наследуется и не реализует тип ограничения 'IAddable (Of T As {Structure, IComparable})' ".

Только то, что я думаю, что структура Int64Calculator действительно реализует это ограничение через Implements IAddable(Of Int64).

Что мне не хватает?

1 Ответ

1 голос
/ 22 апреля 2019

Часть 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,тогда следующий код вернет пригодный для использования HashCode.

public override int GetHashCode() { return Tuple.Create(Name, PhoneNumber).GetHashCode(); }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...