在对ArrayList中的项进行IndexOf时,不会调用覆盖Equals方法 [英] Overriding Equals method not being called when doing IndexOf an item in an ArrayList

查看:80
本文介绍了在对ArrayList中的项进行IndexOf时,不会调用覆盖Equals方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过阅读文档,这应该是一件相对容易的事情。我

有一个自定义类实例的arraylist,我想搜索

和indexof如果只有

搜索的类,我正在传递一个实例。财产有价值。我希望将索引放到

arraylist中,然后我可以获得整个类实例。但是,

''indexof''永远不会调用我的重载,覆盖Equals方法。这是

代码片段:

Private Sub Form1_Load(ByVal sender As System.Object,ByVal e As

系统。 EventArgs)处理MyBase.Load


Dim PeopleCollection作为新的ArrayList


将客户视为新人

客户。年龄= 25

Customer.IsMale =" Yes"


PeopleCollection.Add(客户)


昏暗y作为新人

y.Age = 25

Dim x As Integer = PeopleCollection.IndexOf(y)''这总是

返回 - 1,意思是它不匹配任何东西

End Sub


公共类人员

私人_IsMale As String

Private _age As Integer

公共重载覆盖函数equals(ByVal obj As Object)As Boolean

如果obj是Nothing则返回False

如果Me.GetType是obj.GetType那么

返回Me.Age = CType(obj,Person).Age

结束如果

结束功能

公共财产IsMale()为字符串

获取

返回_IsMale

结束获取

设置(ByVal值为字符串)

_IsMale =价值

结束集

结束财产

公共财产年龄( )作为整数

获取

返回_age

结束获取

设置(ByVal值为整数)

_age =价值

结束套件

结束物业

结束等级


在这个例子中,我想得到年龄为25岁的PERSON的实例。

如果我在我的重载中设置断点覆盖equals方法,它永远不会打破
。我的EQUALS方法没有被调用。


任何人都可以解释发生了什么,以及如何让我的索引完成

我需要它做什么?


谢谢,John

解决方案



JohnR写道:< blockquote class =post_quotes>从阅读文档中,这应该是一个相对简单的
的东西。我有一个自定义类实例的arraylist,我想用indexof搜索
如果只有
搜索的类,我正在传递一个实例。财产有价值。我希望索引到
arraylist然后我可以得到整个类实例。
但是,''indexof''永远不会调用我的重载,覆盖Equals方法。
以下是代码片段:

Private Sub Form1_Load(ByVal sender As System.Object,ByVal e As
System.EventArgs)处理MyBase.Load

Dim PeopleCollection As New ArrayList

将客户视为新人
Customer.Age = 25
Customer.IsMale =" Yes"

PeopleCollection 。添加(客户)

Dim y As New Person
y.Age = 25
Dim x As Integer = PeopleCollection.IndexOf(y)''这总是
返回-1,意味着它不匹配任何东西
End Sub

公共类人员
私有_IsMale As String
私有_age作为整数
公开重载覆盖函数equals(ByVal obj As Object)As
Boolean如果obj为Nothing则返回False
如果Me.GetType为obj.GetType则
返回Me.Age = CType(obj,Person ).Age
结束如果
结束函数
[snip]
在这个例子中我想得到年龄
为25的PERSON实例。如果我在我的重载中设置一个断点覆盖equals方法,
永远不会中断。我的EQUALS方法没有被调用。

任何人都可以解释发生了什么,以及如何将我的索引转换为
做我需要做的事情?




这在技术上是一个特征而不是一个bug(我不知道),因为

行为是记录在案的。在ArrayList.IndexOf的文档中,你会看到
看到它说:


备注

....

此方法通过调用Object.Equals来确定相等。




这就是为什么你的班级的Equals方法没有被调用。要获得

的行为,你希望你有很多选择,其中包括

我认为最明显的两个:


- 实现一个强类型的ArrayList,用于存储Person

对象,在执行IndexOf操作时使用Person.Equals;


- 使用不同的集合class,一个明确支持使用覆盖等于运算符的
。例如,Hashtable使用

Equals实现的关键对象,而不是总是使用

Object.Equals


如果你需要枯萎或者这两个选项解释得更多,随意

问:)


-

Larry Lard

回复团体请


嗨拉里,

- 强烈实施typed ArrayList,用于存储
Person对象,在执行IndexOf
操作时使用Person.Equals;


我不完全确定你的意思。 ..


每个进入arraylist的人都是PERSON类型。但是,仍然,
的索引没有在Person类中调用object.equals。我猜测它是调用了ArrayList类中的object.equals方法,所以我尝试了

来创建一个继承自arraylist的新类ARRAYLISTPERSON 。然后我将
将覆盖重载函数等于(byval obj作为对象)作为boolean

在arraylistperson类def''n中并将我的PERSON实例存储在此

类而不是常规的arraylist类。不幸的是,当调用

indexof方法时,我的Equals函数没有被调用,所以我仍然不知所措。$ / b


你有一个小代码示例,说明如何覆盖arraylist.indexof的Object.equals

方法吗?


谢谢,John

" Larry Lard" < LA ******* @ hotmail.com>在留言中写道

news:11 ********************** @ f14g2000cwb.googlegr oups.com ......
JohnR写道:

从阅读文档,这应该是一个相对简单的


的事情。我

有一个自定义类实例的arraylist,我想搜索


" indexof"如果只有


" search的类,我正在传递一个实例财产有价值。我希望将索引转换为


arraylist,然后我可以获取整个类实例。


但是,

''indexof''永远不会调用我的重载,覆盖Equals方法。


这是

代码片段:

私有Sub Form1_Load(ByVal sender As System.Object,ByVal e As
System.EventArgs)处理MyBase.Load

Dim PeopleCollection作为新ArrayList

将客户视为新人物
Customer.Age = 25
Customer.IsMale =" Yes"

PeopleCollection.Add(客户)

Dim y As New Person
y.Age = 25
Dim x As Integer = PeopleCollection.IndexOf(y)''这总是
返回-1,意味着它不匹配任何东西
End Sub <公共类人员
私有_IsMale作为字符串
私有_age作为整数
公共过载O verrides函数equals(ByVal obj As Object)As


Boolean

如果obj为Nothing则返回False
如果Me.GetType为obj.GetType则
返回Me.Age = CType(obj,Person).Age
结束如果
结束功能


[snip]


In这个例子我想获得年龄


为25的PERSON实例。

如果我在我的重载中放置一个断点,则覆盖equals方法,它

<从来没有

休息。我的EQUALS方法没有被调用。

任何人都可以解释发生了什么,以及如何将我的索引转换为


什么我需要它吗?



这在技术上是一个特征而不是一个bug(我不知道),因为
行为是记录的。在ArrayList.IndexOf的文档中,你会看到它说:

备注
...
此方法通过调用Object.Equals来确定相等性。



这就是为什么没有调用类的Equals方法。为了获得你想要的行为,你有很多选择,其中包括这些......我认为最明显的两个:

- 实现一个强类型的ArrayList来存储单独的Person
对象,在执行IndexOf操作时使用Person.Equals;

- 使用不同的集合类,明确支持使用覆盖等于运算符的集合类。例如,Hashtable使用
Equals实现的关键对象,而不是总是使用
Object.Equals

如果你需要枯萎或者这两个选项都解释得更多,感觉免费
要问:)

-
拉里拉德
回复团体请



< blockquote>

JohnR写道:

嗨拉里,

> - 实现一个强类型的ArrayList,用于存储

Person

>对象,在执行


IndexOf操作时使用Person.Equals;

我不完全确定你的意思......

每个进入arraylist的人都是PERSON类型。但是,仍然,
indexof并没有调用Person类中的object.equals。我猜测
它正在调用ArrayList类中的object.equals方法,


ArrayList将*总是*使用Object.Equals(等于在IndexOf

方法中检查相等性时,在基类Object中定义了
。这就是ArrayList的实现方式。


所以我试着创建一个继承自arraylist的新类ARRAYLISTPERSON。
然后我将覆盖重载函数equals(byval obj as object)作为
boolean在arraylistperson类def''n中并将我的PERSON实例存储在
这个类而不是常规arraylist类中。不幸的是,当
调用indexof方法时,我的Equals函数没有被调用,所以我仍然是
亏本。


提供一个新的Equals方法,无论你做什么,都不会改变

ArrayList的行为 - 它总是会使用Object.Equals。

你有一个小代码示例,说明如何覆盖arraylist.indexof的
Object.equals方法?


改变行为需要的是* IndexOf *方法。这里

是一般的想法:

公共类ArrayListOfPerson

继承ArrayList


公共阴影函数IndexOf(ByVal p As Person)作为整数

将iterp视为人物

Dim i as Integer


For i = 0 To Me.Count - 1

iterp = DirectCast(Me(i),Person)

如果p.Equals(iterp)然后返回i

下一页


返回-1

结束功能

结束班级


用法示例:


Dim al As ArrayList = New ArrayList


al.Add(New Person(10))

al.Add(新人(5))


MsgBox(al.IndexOf(新人(5)))

''这个将显示-1,因为ArrayList使用Object.Equals来执行IndexOf方法

''和Object.Equals需要参考等价


Dim alp As ArrayListOfPerson = New ArrayListOfPerson


alp.Add (新人(10))

alp.Add(新人(5))


MsgBox(alp.IndexOf(新人(5)))

''这将返回1,因为ArrayListOfPerson在执行IndexOf(作为人物)时使用

Person.Equals

''

****请注意****这在很多方面都缺乏稳健性,

这是*不*我将如何建议实施强类型

收集任何大于玩具的东西(即仅限个人用途)

申请。主要的问题是:没有什么可以阻止添加非Person的ArrayListOfPerson的粗略客户端。 Item()

属性仍然作为Object返回,因此必须转换为Person;一个

ArrayListOfPerson可以下传到ArrayList并失去它所有的自定义行为。重申一下,不要以这种方式做自定义集合
seroius应用程序中的
!这只是一个例子!您可以在

上找到许多帖子,以便在此组中实现自定义集合的正确方法。或者

开始一个新的主题并问,因为这是一个单独的主题:)

谢谢,John

" Larry Lard" < LA ******* @ hotmail.com>在消息中写道
新闻:11 ********************** @ f14g2000cwb.googlegr oups.com ...


JohnR写道:

从阅读文档,这应该是一个相对简单的


的事情。我

有一个自定义类实例的arraylist,我想搜索


" indexof"我正在传递一个实例,如果只有
的类

" search"财产有价值。我希望将索引转换为


arraylist,然后我可以获取整个类实例。


但是,

''indexof''永远不会调用我的重载,覆盖Equals方法。


这是

代码片段:

私有Sub Form1_Load(ByVal sender As System.Object,ByVal e As
System.EventArgs)处理MyBase.Load

Dim PeopleCollection作为新ArrayList

将客户视为新人物
Customer.Age = 25
Customer.IsMale =" Yes"

PeopleCollection.Add(客户)

Dim y As New Person
y.Age = 25
Dim x As Integer = PeopleCollection.IndexOf(y)''this


总是返回-1,意味着它没有匹配任何东西
结束子

公共类人员
私人_IsMale作为字符串
私人_age作为整数
公开重载覆盖函数equals(ByVal obj As Object)As


Boolean

如果obj为Nothing则返回False
如果Me.GetType为obj.GetType则结束如果
结束函数


[snip]


在这个例子中,我想获得PERSON的实例



age是25.

如果我放了一个断点在我的重载中覆盖equals方法,它


从不

中断。我的EQUALS方法没有被调用。

任何人都可以解释发生了什么,以及如何让我的indexof


来做

什么我需要它吗?



这在技术上是一个功能而不是一个bug(我不知道),因为
行为是记录在案的。在ArrayList.IndexOf的文档中,你
会看到它说:


备注
...
此方法通过调用Object.Equals来确定相等性。



这就是为什么没有调用类的Equals方法。为了获得
您想要的行为,您有许多选择,其中包括这些
,因为我认为最明显的两个:

- 实现强类型ArrayList以便仅存储Person
对象,在执行IndexOf操作时使用Person.Equals;

- 使用不同的集合类,一个明确支持
使用覆盖等于运算符的集合类。例如,Hashtable使用
关键对象的Equals实现,而不是总是使用
Object.Equals

如果你需要枯萎或者这两个选项都解释得更多,感觉
免费提问:)

-
Larry Lard
回复团体




From reading the documentation, this should be a relatively easy thing. I
have an arraylist of custom class instances which I want to search with
an"indexof" where I''m passing an instance if the class where only the
"searched" property has a value. I expected to get the index into the
arraylist where I could then get the entire class instance. However, the
''indexof'' is never calling my overloaded, overrides Equals method. Here is
the code snippet:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim PeopleCollection As New ArrayList

Dim Customer As New Person
Customer.Age = 25
Customer.IsMale = "Yes"

PeopleCollection.Add(Customer)

Dim y As New Person
y.Age = 25
Dim x As Integer = PeopleCollection.IndexOf(y) ''this always
returns -1, meaning it didn''t match anything
End Sub

Public Class Person
Private _IsMale As String
Private _age As Integer
Public Overloads Overrides Function equals(ByVal obj As Object) As Boolean
If obj Is Nothing Then Return False
If Me.GetType Is obj.GetType Then
Return Me.Age = CType(obj, Person).Age
End If
End Function
Public Property IsMale() As String
Get
Return _IsMale
End Get
Set(ByVal Value As String)
_IsMale = Value
End Set
End Property
Public Property Age() As Integer
Get
Return _age
End Get
Set(ByVal Value As Integer)
_age = Value
End Set
End Property
End Class

In this example I wanted to get the instance of the PERSON whose age is 25.
If I put a breakpoint in my overloads overrides equals method, it never
breaks. My EQUALS method is not being called.

Can anybody explain what is going on, and how I can get my indexof to do
what I need it to do?

Thanks, John

解决方案


JohnR wrote:

From reading the documentation, this should be a relatively easy thing. I have an arraylist of custom class instances which I want to search with an"indexof" where I''m passing an instance if the class where only the "searched" property has a value. I expected to get the index into the arraylist where I could then get the entire class instance. However, the ''indexof'' is never calling my overloaded, overrides Equals method. Here is the code snippet:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim PeopleCollection As New ArrayList

Dim Customer As New Person
Customer.Age = 25
Customer.IsMale = "Yes"

PeopleCollection.Add(Customer)

Dim y As New Person
y.Age = 25
Dim x As Integer = PeopleCollection.IndexOf(y) ''this always
returns -1, meaning it didn''t match anything
End Sub

Public Class Person
Private _IsMale As String
Private _age As Integer
Public Overloads Overrides Function equals(ByVal obj As Object) As Boolean If obj Is Nothing Then Return False
If Me.GetType Is obj.GetType Then
Return Me.Age = CType(obj, Person).Age
End If
End Function [snip]
In this example I wanted to get the instance of the PERSON whose age is 25. If I put a breakpoint in my overloads overrides equals method, it never breaks. My EQUALS method is not being called.

Can anybody explain what is going on, and how I can get my indexof to do what I need it to do?



This is technically a feature not a bug (doesn''t help I know), as the
behaviour is as documented. In the docs for ArrayList.IndexOf, you will
see it says:

Remarks
....
This method determines equality by calling Object.Equals.



which is why your class''s Equals method is not being called. To get the
behaviour you want you have a number of choices which include these as
I think the most obvious two:

- Implement a strongly-typed ArrayList for storing solely Person
objects, that uses Person.Equals when doing an IndexOf operation;

- Use a different collection class, one that explicitly supports the
use of overriden Equals operators. For example, a Hashtable uses the
Equals implementation of the key objects, rather than always using
Object.Equals

If you need wither or both of these options explained more, feel free
to ask :)

--
Larry Lard
Replies to group please


Hi Larry,

- Implement a strongly-typed ArrayList for storing solely Person objects, that uses Person.Equals when doing an IndexOf operation;

I''m not exactly sure what you mean...

Every entry into the arraylist was of type PERSON. But, still, the indexof
didn''t call the object.equals in the Person class. I''m guessing that it is
calling a object.equals method that is in the ArrayList class, so I tried
to create a new class ARRAYLISTPERSON which inherits from arraylist. I then
put the overrides overloads function equals(byval obj as object) as boolean
in the arraylistperson class def''n and stored my PERSON instances in this
class rather than the regular arraylist class. Unfortunately, when the
indexof method was called, my Equals function was not called, so I''m still
at a loss.

Do you have a small code example of how to override the Object.equals
method of an arraylist.indexof?

Thanks, John
"Larry Lard" <la*******@hotmail.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...
JohnR wrote:

From reading the documentation, this should be a relatively easy


thing. I

have an arraylist of custom class instances which I want to search


with

an"indexof" where I''m passing an instance if the class where only the


"searched" property has a value. I expected to get the index into


the

arraylist where I could then get the entire class instance.


However, the

''indexof'' is never calling my overloaded, overrides Equals method.


Here is

the code snippet:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim PeopleCollection As New ArrayList

Dim Customer As New Person
Customer.Age = 25
Customer.IsMale = "Yes"

PeopleCollection.Add(Customer)

Dim y As New Person
y.Age = 25
Dim x As Integer = PeopleCollection.IndexOf(y) ''this always
returns -1, meaning it didn''t match anything
End Sub

Public Class Person
Private _IsMale As String
Private _age As Integer
Public Overloads Overrides Function equals(ByVal obj As Object) As


Boolean

If obj Is Nothing Then Return False
If Me.GetType Is obj.GetType Then
Return Me.Age = CType(obj, Person).Age
End If
End Function


[snip]


In this example I wanted to get the instance of the PERSON whose age


is 25.

If I put a breakpoint in my overloads overrides equals method, it


never

breaks. My EQUALS method is not being called.

Can anybody explain what is going on, and how I can get my indexof to


do

what I need it to do?



This is technically a feature not a bug (doesn''t help I know), as the
behaviour is as documented. In the docs for ArrayList.IndexOf, you will
see it says:

Remarks
...
This method determines equality by calling Object.Equals.



which is why your class''s Equals method is not being called. To get the
behaviour you want you have a number of choices which include these as
I think the most obvious two:

- Implement a strongly-typed ArrayList for storing solely Person
objects, that uses Person.Equals when doing an IndexOf operation;

- Use a different collection class, one that explicitly supports the
use of overriden Equals operators. For example, a Hashtable uses the
Equals implementation of the key objects, rather than always using
Object.Equals

If you need wither or both of these options explained more, feel free
to ask :)

--
Larry Lard
Replies to group please




JohnR wrote:

Hi Larry,

> - Implement a strongly-typed ArrayList for storing solely

Person

> objects, that uses Person.Equals when doing an

IndexOf operation;

I''m not exactly sure what you mean...

Every entry into the arraylist was of type PERSON. But, still, the indexof didn''t call the object.equals in the Person class. I''m guessing that it is calling a object.equals method that is in the ArrayList class,
An ArrayList will *always* use Object.Equals (the Equals method defined
in the base class Object) when checking for equality in its IndexOf
method. That is just the way ArrayList is implemented.

so I tried
to create a new class ARRAYLISTPERSON which inherits from arraylist. I then put the overrides overloads function equals(byval obj as object) as boolean in the arraylistperson class def''n and stored my PERSON instances in this class rather than the regular arraylist class. Unfortunately, when the indexof method was called, my Equals function was not called, so I''m still at a loss.
Supplying a new Equals method, wherever you do it, won''t change
ArrayList''s behaviour - it will always use Object.Equals.

Do you have a small code example of how to override the Object.equals method of an arraylist.indexof?
What you need to change the behaviour of is the *IndexOf* method. Here
is the general idea:

Public Class ArrayListOfPerson
Inherits ArrayList

Public Shadows Function IndexOf(ByVal p As Person) As Integer
Dim iterp As Person
Dim i As Integer

For i = 0 To Me.Count - 1
iterp = DirectCast(Me(i), Person)
If p.Equals(iterp) Then Return i
Next

Return -1
End Function
End Class

Usage example:

Dim al As ArrayList = New ArrayList

al.Add(New Person(10))
al.Add(New Person(5))

MsgBox(al.IndexOf(New Person(5)))
''this will show -1, because ArrayList uses Object.Equals to
compare
''while performing the IndexOf method
''and Object.Equals requires reference equivalence

Dim alp As ArrayListOfPerson = New ArrayListOfPerson

alp.Add(New Person(10))
alp.Add(New Person(5))

MsgBox(alp.IndexOf(New Person(5)))
''this will return 1, because ArrayListOfPerson uses
Person.Equals
''while performing IndexOf(As Person)
**** PLEASE NOTE **** that this lacks robustness in a number of ways,
and this is *not* how I would suggest implementing a strongly-typed
collection in anything larger than a toy (ie personal-use only)
application. The main problems are that: There is nothing to stop a
careless client of ArrayListOfPerson adding a non-Person; the Item()
property is still returned As Object so must be casted to Person; an
ArrayListOfPerson can be casted down to ArrayList and lose all its
custom behaviour. To reiterate, DON''T do custom collections in this way
in seroius apps! This is just an example! You can find many posts on
the correct ways to implement custom collections here in this group. Or
start a new thread and ask, as that is a separate topic :)

Thanks, John
"Larry Lard" <la*******@hotmail.com> wrote in message
news:11**********************@f14g2000cwb.googlegr oups.com...


JohnR wrote:

From reading the documentation, this should be a relatively easy


thing. I

have an arraylist of custom class instances which I want to search


with

an"indexof" where I''m passing an instance if the class where only the

"searched" property has a value. I expected to get the index into


the

arraylist where I could then get the entire class instance.


However, the

''indexof'' is never calling my overloaded, overrides Equals method.


Here is

the code snippet:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim PeopleCollection As New ArrayList

Dim Customer As New Person
Customer.Age = 25
Customer.IsMale = "Yes"

PeopleCollection.Add(Customer)

Dim y As New Person
y.Age = 25
Dim x As Integer = PeopleCollection.IndexOf(y) ''this

always returns -1, meaning it didn''t match anything
End Sub

Public Class Person
Private _IsMale As String
Private _age As Integer
Public Overloads Overrides Function equals(ByVal obj As Object) As


Boolean

If obj Is Nothing Then Return False
If Me.GetType Is obj.GetType Then
Return Me.Age = CType(obj, Person).Age
End If
End Function


[snip]


In this example I wanted to get the instance of the PERSON whose


age is 25.

If I put a breakpoint in my overloads overrides equals method, it


never

breaks. My EQUALS method is not being called.

Can anybody explain what is going on, and how I can get my indexof

to do

what I need it to do?



This is technically a feature not a bug (doesn''t help I know), as the behaviour is as documented. In the docs for ArrayList.IndexOf, you will see it says:


Remarks
...
This method determines equality by calling Object.Equals.



which is why your class''s Equals method is not being called. To get the behaviour you want you have a number of choices which include these as I think the most obvious two:

- Implement a strongly-typed ArrayList for storing solely Person
objects, that uses Person.Equals when doing an IndexOf operation;

- Use a different collection class, one that explicitly supports the use of overriden Equals operators. For example, a Hashtable uses the Equals implementation of the key objects, rather than always using
Object.Equals

If you need wither or both of these options explained more, feel free to ask :)

--
Larry Lard
Replies to group please




这篇关于在对ArrayList中的项进行IndexOf时,不会调用覆盖Equals方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆