Обратиться к элементу HashTable по его ключу (ключ - объект)

Язык Visual Basic на платформе .NET.

Модераторы: Ramzes, Sebas

Anatoliy
Новичок
Новичок
 
Сообщения: 28
Зарегистрирован: 12.01.2005 (Ср) 18:13
Откуда: Kiev

Обратиться к элементу HashTable по его ключу (ключ - объект)

Сообщение Anatoliy » 15.02.2005 (Вт) 18:28

Добрый день
Возможно ли обратиться к элементу HashTable по его ключу, если ключ - это экземпляр собственного класса.
Чтобы прояснить, что же я сам спросил, приведу код:
Есть модуль с тремя классами:
cPoint - координаты ячейки (индекс строки и столбца)
cCell - основные характеристики ячейки - координаты, текст
cSheet - рабочий лист (семейство заполненных текстом ячеек)

Код: Выделить всё
Module TestModule

    Public Class cPoint
        'координаты ячейки
        Dim _Row As Integer
        Dim _Col As Integer
        Public Property Row() As Integer
            Get
                Row = _Row
            End Get
            Set(ByVal Value As Integer)
                _Row = Value
            End Set
        End Property
        Public Property Col() As Integer
            Get
                Col = _Col
            End Get
            Set(ByVal Value As Integer)
                _Col = Value
            End Set
        End Property
    End Class

    Public Class cCell
        'основные характеристики ячейки - координаты, текст
        Dim _Point As cPoint
        Dim _Text As String
        Public Sub New(ByVal Pt As cPoint, ByVal str As String)
            Me.Point = Pt
            Me.Text = str
        End Sub
        Public Sub New()

        End Sub
        Public Property Point() As cPoint
            Get
                Point = _Point
            End Get
            Set(ByVal Value As cPoint)
                _Point = Value
            End Set
        End Property
        Public Property Text() As String
            Get
                Text = _Text
            End Get
            Set(ByVal Value As String)
                _Text = Value
            End Set
        End Property
    End Class

    Public Class cSheet
        'рабочий лист (семейство заполненных текстом ячеек)
        Dim _htCell As New Hashtable
        Public Sub Add(ByVal Cl As cCell)
            _htCell.Add(Cl.Point, Cl)
        End Sub
        Public Function Item(ByVal iRow As Integer, ByVal iCol As Integer)
            Dim Pt As New cPoint
            Dim Cl As New cCell
            Pt.Col = iCol
            Pt.Row = iRow
            'Имеем экземпляр Pt типа cPoint
            'В хештаблице точно есть экземпляр с аналогичным ключем 0;0.
            'Как обратиться к значению???
            If _htCell.ContainsKey(Pt) Then MsgBox("Exists point with row: " & Pt.Row.ToString & " and col: " & Pt.Col.ToString)
            Cl = _htCell.Item(Pt) 'получаем Nothing
        End Function
    End Class
End Module


Запускаем тестирование:

Код: Выделить всё
  Private Sub Button7_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button7.Click
        Dim Cl(2) As cCell
        Dim ClTmp As cCell
        Dim i As Integer
        Dim St As New cSheet
        Dim Pt As cPoint
        Dim iRow As Integer = 0
        For i = LBound(Cl) To UBound(Cl)
            Pt = New cPoint
            Pt.Col = i
            Pt.Row = iRow
            Cl(i) = New cCell(Pt, Chr(i + 65) & iRow.ToString)
            St.Add(Cl(i))
        Next
        'точно знаем, что в хештаблице есть элементы с ключами 0;0, 0;1, 0;2
        Pt = New cPoint
        Pt.Col = 0
        Pt.Row = 0
        ClTmp = St.Item(Pt.Row, Pt.Col)
    End Sub
Anatoliy

areh
Постоялец
Постоялец
 
Сообщения: 530
Зарегистрирован: 02.12.2002 (Пн) 12:28
Откуда: РОССИЯ, Салехард

Сообщение areh » 15.02.2005 (Вт) 22:20

вообще это допускается, но твой пример не работает по 2 причинам:

1. ключ должен быть не только с теми же самыми значениями свойств, но он должен быть и тем же самым объектом! т.е. если ты создаш два объекта и присвоишь их полям (свойствам) одни и те же значения, это будут разные ключи. как выход, в качестве ключей используй не класс, а структуру (Structure)

2. Твоя функция Item ничего не возвращает в основную программу, т.е. там надо в конце добавить строку "Return Cl" или "Item = Cl"

вот так вот...

---
В итоге оно может выглядеть (да ещё и работать) вот так:

Код: Выделить всё
Module TestModule

  Public Structure cPoint
    'координаты ячейки
    Public Row As Integer
    Public Col As Integer
  End Structure

  Public Class cCell
    'основные характеристики ячейки - координаты, текст
    Dim _Point As cPoint
    Dim _Text As String
    Public Sub New(ByVal Pt As cPoint, ByVal str As String)
      Me.Point = Pt
      Me.Text = str
    End Sub
    Public Sub New()

    End Sub
    Public Property Point() As cPoint
      Get
        Point = _Point
      End Get
      Set(ByVal Value As cPoint)
        _Point = Value
      End Set
    End Property
    Public Property Text() As String
      Get
        Text = _Text
      End Get
      Set(ByVal Value As String)
        _Text = Value
      End Set
    End Property
  End Class

  Public Class cSheet
    'рабочий лист (семейство заполненных текстом ячеек)
    Dim _htCell As New Hashtable
    Public Sub Add(ByVal Cl As cCell)
      _htCell.Add(Cl.Point, Cl)
    End Sub
    Public Function Item(ByVal iRow As Integer, ByVal iCol As Integer) As cCell
      Dim Pt As New cPoint
      Dim Cl As New cCell
      Pt.Col = iCol
      Pt.Row = iRow
      'Имеем экземпляр Pt типа cPoint
      'В хештаблице точно есть экземпляр с аналогичным ключем 0;0.
      'Как обратиться к значению???
      If _htCell.ContainsKey(Pt) Then MsgBox("Exists point with row: " & Pt.Row.ToString & " and col: " & Pt.Col.ToString)
      Cl = _htCell.Item(Pt) 'получаем Nothing
      Return Cl
    End Function
  End Class
End Module

Anatoliy
Новичок
Новичок
 
Сообщения: 28
Зарегистрирован: 12.01.2005 (Ср) 18:13
Откуда: Kiev

Применять вместо объекта класса аналогичную структуру

Сообщение Anatoliy » 16.02.2005 (Ср) 11:14

Спасибо за идею. Действительно, если использовать структуру, то можно обращаться к элементам HashTable, используя экземпляры структуры.
Чтобы не переписывать весь код (то что я привел, только часть), изменил модуль:


Код: Выделить всё
Module TestModule

    Public Structure cPointStruct
        Public Row As Integer
        Public Col As Integer
    End Structure

    Public Class cPoint
        'координаты ячейки (индекс строки и столбца)
        Dim _Row As Integer
        Dim _Col As Integer

        Public Property Row() As Integer
            Get
                Row = _Row
            End Get
            Set(ByVal Value As Integer)
                _Row = Value
            End Set
        End Property
        Public Property Col() As Integer
            Get
                Col = _Col
            End Get
            Set(ByVal Value As Integer)
                _Col = Value
            End Set
        End Property
        Public Property PointAsStruct() As cPointStruct
            Get
                Dim PntStr As cPointStruct
                PntStr.Row = Me.Row
                PntStr.Col = Me.Col
                PointAsStruct = PntStr
            End Get
            Set(ByVal pPntStr As cPointStruct)
                Me.Row = pPntStr.Row
                Me.Col = pPntStr.Col
            End Set
        End Property
    End Class

    Public Class cCell
        'основные характеристики ячейки - координаты, текст
        Dim _Point As cPoint
        Dim _Text As String
        Public Sub New(ByVal Pt As cPoint, ByVal str As String)
            Me.Point = Pt
            Me.Text = str
        End Sub
        Public Sub New()

        End Sub
        Public Property Point() As cPoint
            Get
                Point = _Point
            End Get
            Set(ByVal Value As cPoint)
                _Point = Value
            End Set
        End Property
        Public Property Text() As String
            Get
                Text = _Text
            End Get
            Set(ByVal Value As String)
                _Text = Value
            End Set
        End Property
    End Class

    Public Class cSheet
        'рабочий лист (семейство заполненных текстом ячеек)
        Dim _htCell As New Hashtable
        Public Sub Add(ByVal Cl As cCell)
            'В качестве ключей добавляем не объект класса cPoint, а структуру cPointStruct
            _htCell.Add(Cl.Point.PointAsStruct, Cl)
        End Sub
        Public Function Item(ByVal iRow As Integer, ByVal iCol As Integer)
            Dim PtS As New cPointStruct
            Dim Cl As New cCell
            PtS.Col = iCol
            PtS.Row = iRow
            If _htCell.ContainsKey(PtS) Then MsgBox("Exists point with row: " & PtS.Row.ToString & " and col: " & PtS.Col.ToString)
            Cl = _htCell.Item(PtS) 'вот теперь получаем объект cCell
        End Function
    End Class
End Module


Т.е. основное изменение - при добавлении элемента в таблицу использую структуру
Anatoliy


Вернуться в Visual Basic .NET

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 66

    TopList