Переопределение GetHashCode в VB без поддержки ключевого слова checked / unchecked?

да indeedy. В особенности Вы видите проблемы с "кучей" отладки/выпуска, являющейся отличающимся, также если Ваша библиотека будет использовать новое размещение, или какая-либо пользовательская "куча", то у Вас будет проблема. Проблема Отладки/Выпуска безусловно наиболее распространена все же.

24
задан Community 23 May 2017 в 12:01
поделиться

3 ответа

Используйте Long, чтобы избежать переполнения:

Dim hash As Long = 17
'' etc..
Return CInt(hash And &H7fffffffL)

Оператор And обеспечивает исключение переполнения. Это, однако, теряет один бит «точности» в вычисленном хеш-коде, результат всегда положительный. VB.NET не имеет встроенной функции, чтобы избежать этого, но вы можете использовать хитрость:

Imports System.Runtime.InteropServices

Module NoOverflows
    Public Function LongToInteger(ByVal value As Long) As Integer
        Dim cast As Caster
        cast.LongValue = value
        Return cast.IntValue
    End Function

    <StructLayout(LayoutKind.Explicit)> _
    Private Structure Caster
        <FieldOffset(0)> Public LongValue As Long
        <FieldOffset(0)> Public IntValue As Integer
    End Structure
End Module

Теперь вы можете написать:

Dim hash As Long = 17
'' etc..
Return NoOverflows.LongToInteger(hash)
23
ответ дан 28 November 2019 в 23:30
поделиться

Улучшенный ответ Переопределение GetHashCode в VB без поддержки отмеченных / непроверенных ключевых слов?

Public Overrides Function GetHashCode() as Integer
  Dim hashCode as Long = 0
  If myReplacePattern IsNot Nothing Then _
    hashCode = ((hashCode*397) Xor myField.GetHashCode()) And &HffffffffL
  If myPattern IsNot Nothing Then _
    hashCode = ((hashCode*397) Xor myOtherField.GetHashCode()) And &HffffffffL
  Return CInt(hashCode)
End Function

После каждого умножения происходит обрезка. И литерал определен явно как Long, потому что оператор And с аргументом Integer не обнуляет старшие байты.

2
ответ дан 28 November 2019 в 23:30
поделиться

После исследования того, что VB не дал нам ничего подобного unchecked, и немного рассерженного (c # dev сейчас делает vb), я реализовал решение, близкое к тому, которое написал Ханс Пассант. Я потерпел неудачу в этом. Ужасная производительность. Это, безусловно, было связано с моей реализацией, а не с решением, опубликованным Хансом. Я мог бы вернуться и более внимательно скопировать его решение.

Однако я решил проблему с другим решением. Сообщение с жалобой на отсутствие unchecked на странице запросов возможностей языка VB дало мне идею использовать алгоритм хэширования уже в рамках. В моей задаче у меня были String и Guid, которые я хотел использовать для словарного ключа. Я решил, что Tupple(Of Guid, String) будет хорошим внутренним хранилищем данных.

Оригинальная плохая версия

Public Structure HypnoKey
  Public Sub New(name As String, areaId As Guid)
    _resourceKey = New Tuple(Of Guid, String)(resourceAreaId, key)
  End Sub

  Private ReadOnly _name As String
  Private ReadOnly _areaId As Guid

  Public ReadOnly Property Name As String
    Get
      Return _name 
    End Get
  End Property

  Public ReadOnly Property AreaId As Guid
    Get
      Return _areaId 
    End Get
  End Property

  Public Overrides Function GetHashCode() As Integer
    'OMFG SO BAD
    'TODO Fail less hard
  End Function

End Structure

Значительно улучшенная версия

Public Structure HypnoKey
  Public Sub New(name As String, areaId As Guid)
    _innerKey = New Tuple(Of Guid, String)(areaId , key)
  End Sub

  Private ReadOnly _innerKey As Tuple(Of Guid, String)

  Public ReadOnly Property Name As String
    Get
      Return _innerKey.Item2
    End Get
  End Property

  Public ReadOnly Property AreaId As Guid
    Get
      Return _innerKey.Item1
    End Get
  End Property

  Public Overrides Function GetHashCode() As Integer
    Return _innerKey.GetHashCode() 'wow! such fast (enuf)
  End Function

End Structure

Итак, хотя я ожидаю, что есть гораздо лучшие решения, чем это я очень счастлив. У меня хорошее выступление. Кроме того, неприятный код утилиты исчез. Надеюсь, что это полезно для некоторых других бедных разработчиков, вынужденных написать VB, который сталкивается с этим постом.

Ура

1
ответ дан 28 November 2019 в 23:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: