开发者

Delphi Prism: How to override GetHashCode and Equals method for IndexOf to work correctly?

开发者 https://www.devze.com 2023-04-05 17:46 出处:网络
I am not sure if I am doing this right. I have a list of objects in the listbox and need to use IndexOf to get an object\'s index in the list.

I am not sure if I am doing this right. I have a list of objects in the listbox and need to use IndexOf to get an object's index in the list.

if AlarmListBox.items.indexOf(alrm.Tagname) = -1 then

alrm is an object of TAlarm class.

Based on a StackOverflow C# question (How Can I Get the Index of An Item in a ListBox?), I try to override GetHashCode and Equals method, but still it doesn't work right.

Overriden Method:

TAlarm = class(System.Object)
  TagName:string;
  private
  protected
  public
  method Equals(obj:System.Object):Boolean; override;
  method GetHashCode:Int32; Override;
end;

method TAlarm.Equals(obj: system.Object):Boolean;
begin
    result := TAlarm(obj).Tagname.Equals(self.Tagname);
end;

method TAlarm.GetHashCode:Int32;
begin
    result := self.GetHashCode;
end;

This is how I populate AlarmListBox:

AlmGrp:= new TAlarmGroup;
AlarmListBox.items.Add(AlmGrp);

Compiler compiles without any errors, but when I debug the program line by line it always returns -1 and these overridden methods are never called or fired.

Am I implementing these overrides correctly? If not, how should I override them?

Sample code or hints or clues will be appreciated. Thanks,

UPDATE: To David Heffernan and others who have commented or answered, I think the problem might be that I am passing in two different object as Rob's last comment states. I do populate Listbox (UI) with TAlarmGroup but pass in TAlarm into IndexOf, although they both are identical classes. This is probably my problem. What I am really trying to do is populate Listbox with TAlarmGroup objects and through listbox.indexof by passing in the string (Tagname) I search for the object location. That's how it is done on Delphi XE it works great. The code above is not the actual code. Once I clean up the confusion in my code, it will probably work without overriding the GetHashcode and Equals method.

UPDATE: I think, I have stumbled onto something here. On Delphi XE or below, ListBox (UI) provides a method called AddObject. It's parameters are a string and an object respectively. So, when I populated objects into listbox I also provi开发者_StackOverflow中文版ded the string to go along with it. When I searched I passed in a string or the alarm group name. IndexOf searched on this string against the string it had for each object I provided and not against the object's field (TagName). In Delphi Prism, listbox doesn't have a similar method as AddObject method but only Add that only accepts object as a parameter.


Here's an example of doing what you want with the base TAlarm class you provided. I've also provided implementations of the overloaded Equals and GetHashCode that seem to work. (Again, I'm not a Prism/.NET developer; just trying to help out here.)

// In AlarmClass.pas
type
  TAlarm = class(System.Object)
    TagName:string;
  private
  protected
  public
    constructor;
    method Equals(obj:System.Object): Boolean; override;
    method GetHashCode:Int32; Override;
    method ToString(): String; override;
end;

implementation

method TAlarm.GetHashCode: Int32;
begin
  if Self = nil then
    Result := inherited 
  else
    Result := Self.TagName.GetHashCode;
end;

constructor TAlarm;
begin
  inherited;
end;

method TAlarm.Equals(obj: System.Object): Boolean;
begin
  if  (obj = nil) or (GetType() <> obj.GetType()) then
    Exit(False);
  Result := TAlarm(obj).TagName.Equals(Self.TagName);
end;

method TAlarm.ToString(): String;
begin
  Result := Self.TagName;
end;

// In MainForm.pas
method MainForm.button1_Click(sender: System.Object; e: System.EventArgs);
var
  Idx: Integer;
begin
  Idx := ComboBox1.SelectedIndex;
  if Idx <> -1 then
    ListBox1.SelectedIndex := ListBox1.Items.IndexOf(ComboBox1.Items[Idx]);
end;

method MainForm.MainForm_Load(sender: System.Object; e: System.EventArgs);
var
  i, j: Integer;
  Alarm: TAlarm;
  aList: Array[0..4] of Object;
  aFind: Array[0..1] of Object;
begin
  j := 0;
  for i := 0 to 4 do
  begin
    Alarm := new TAlarm;
    Alarm.TagName := String.Format('Alarm{0}', i);
    aList[i] := Alarm;
    // Place items 1 & 3 in another array of searchable items -
    // just for fun. Not suggesting implementing your app this way
    // by any means.
    if (i mod 2) > 0 then
    begin
      aFind[j] := Alarm;
      Inc(j);
    end;
  end;
  ListBox1.Items.AddRange(aList);
  ComboBox1.Items.AddRange(aFind);
end;

Here's how it looks with an item selected in the ComboBox after clicking the Button:

Delphi Prism: How to override GetHashCode and Equals method for IndexOf to work correctly?

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号