通用列表的相等比较. [英] Equalitable comparison of generic lists.
问题描述
我创建了一个例程,用于比较2个列表,以查看它们是否相等.这个例程从创建两个列表的按钮开始,而我却想出了解决方案.
I have a routine that I created for comparing 2 lists to see if they are equal or not. This routine started life within a button that the 2 lists were created, while I figured the solution out.
dim aList as new list(of Client)
dim bList as new list(of Client)
'
'fill the 2 lists with identical information
'
Dim Match As Boolean = False
If Not aList.Count = bList.Count Then
'i.e. lists dont match in volume
MsgBox(False)
Else
Dim iPointer As Integer = 0 'list poistion marker
For Each objectType As Client In bList
If objectType.Equals(bList(iPointer)) = False Then
'here if the match is false we dont need to go through the
'rest of the list so exit the for loop and return the result
Dim ObjectDataType As Type = objectType.GetType
ObjectName = ObjectDataType.Name.ToString
Match = False
Exit For
Else
Match = True
End If
'increment the pointer variable
iPointer += 1
Next
End If
MsgBox(Match)
比较来自同一函数的2个列表时,这非常有用.现在,为了使比较功能更可重用,我决定将其设为功能.
This works great when comparing 2 lists from the same function. Now trying to make the compare function more re-usable I decided to make it a function.
Function ListEquals(Of t)(ByVal list1 As List(Of t), ByVal list2 As List(Of t)) As Boolean
Dim Match As Boolean = False
If Not list1.Count = list2.Count Then
'i.e. lists dont match in volume
Return False
Else
Dim iPointer As Integer = 0 'list poistion marker
For Each objectType As t In list2
If objectType.Equals(list1(iPointer)) = False Then
'here if the match is false we dont need to go through
'the rest of the list so exit the for loop and return the result
Dim tt As Type = objectType.GetType
ObjectName = tt.Name.ToString
Match = False
Exit For
Else
Match = True
End If
'increment the pointer variable
iPointer += 1
Next
End If
Return Match
End Function
并将2个相同的列表传递给该函数,则该函数始终返回false,因为代码的第一部分将返回true.
更新-如果我删除"of t"并将其替换为实际类型,即在其起作用的函数中为"of of client",是什么会导致t导致Equalitable不起作用?
任何人都知道要检查什么的指针/想法吗?
谢谢
Simon
and pass in the 2 identical lists to the function it always returns false, where as the first peice of code will return true.
Update - If I remove the "of t" and replace it for actual types i.e. "of client" in the function it works, what would cause t to make the Equalitable to not work?
Anyone got any pointers / ideas of what to check?
Thanks
Simon
推荐答案
这可能与Client类的细节有关.原始代码和通用方法是否实际上调用相同的Equals方法?
如果Client类通过IEquatable实现值相等而又不覆盖Object.Equals方法,则可能会遇到问题.如果是这种情况,则通用方法将通过Object.Equals进行参考比较.
[其他信息]
IEquatable接口声明一个强类型的Equals方法.在使用时,重要的是要确保新的IEquatable.Equals方法和现有的Object.Equals方法都给出相同的结果.该代码示例演示了如何做到这一点,并且我对其进行了设置,以便如果Client对象的Identity属性返回相同的值,则它们被视为相等.
This is probably down to the specifics of the Client class. Do the original code and the generic method actually call the same Equals method?
You could have a problem if the Client class implements value equality via IEquatable without also overriding the Object.Equals method. If this is the case then the generic method would be making a reference comparison via Object.Equals.
[Additional information]
The IEquatable interface declares a strongly typed Equals method. When used it is important to make sure that the new IEquatable.Equals method and the existing Object.Equals method both give the same result. The code example shows how that can be done and I''ve set it up so that Client objects are considered equal if their Identity properties return the same value.
Public Class Client
Implements IEquatable(Of Client)
Private id As Int32
Public ReadOnly Property Identity() As Int32
Get
Return Me.id
End Get
End Property
' IEquatable.Equals
Public Function Equals(other As Client) As Boolean
' other is null
If ReferenceEquals(other, Nothing) Then
Return False
End If
' same object
If ReferenceEquals(Me, other) Then
Return True
End If
' different type, other is derived from Client
If other.GetType() <> Me.GetType() Then
Return False
End If
Return Me.Identity = other.Identity
End Function
Public Overrides Function Equals(other As Object) As Boolean
' call IEquatable.Equals
Return Me.Equals(TryCast(other, Client))
End Function
End Class
Private Function ListEquals(Of T As IEquatable(Of T))(list1 As List(Of T), list2 As List(Of T)) As Boolean
' Note: the constraint allows this method to use of IEquatable.Equals
Dim same As Boolean = list1.Count = list2.Count
Dim i As Int32 = 0
While same AndAlso i < list1.Count
same = list1(i).Equals(list2(i))
i += 1
End While
Return same
End Function
ListEquals方法的约束指定T必须实现IEquatable,最重要的是,允许泛型方法使用新的Equals方法.
没有约束,比较方法将不会知道IEquatable.Equals存在,并且只能使用Object.Equals.对于我的Client实现,这与我的IEquatable.Equals和我的Object.Equals均已编码为给出相同的结果无关.
艾伦.
The constraint on the ListEquals method specifies that T must implement IEquatable and most importantly allows the generic method to use the new Equals method.
Without the constraint the comparison method would not know that IEquatable.Equals existed and it could only use Object.Equals. With my implementation of Client this wouldn''t matter as my IEquatable.Equals and my Object.Equals have been coded to give the same result.
Alan.
首先,您做的很简单-比较具有相同元素类型的列表,因此只能使用一个通用参数-此元素的类型.同样,您也不需要实现IEqualitable
,通常用于比较不同类型的对象.
您的任务要简单得多.从类型System.Collections.Generic.List
派生generic
类型-不是sealed
.在派生类中,覆盖object.Equals
并定义运算符!="和"==".它还需要重写object.GetHashCode
(我必须解释为什么吗?)才能在基于哈希的容器(例如Dictionary
)中有效使用您的类型).您已经知道如何进行比较.只有您忘记将列表实例与null
进行比较.也要这样做,否则您的实现是不正确的.两个null
值比较应返回true.
另外,不要忘记在实现中使用object.ReferencesEquals
而不是"==",这有两个原因:1)如果实现了"==",则如果"=="使用"= =在其实现中; 2)如果两个列表作为引用相等,则没有必要检查列表成员-列表实例已经相等.
—SA
First, you''re doing very simple thing — comparison of lists with the same element type, so you can use only one generic parameter — this element''s type. Also, you don''t need to implementIEqualitable
, which is generally used to compare objects of different types.
Your task is much more simple. Derive ageneric
type from the typeSystem.Collections.Generic.List
— it is notsealed
. In the derived class, overrideobject.Equals
and define operators "!=" and "==". It will also require overriddenobject.GetHashCode
(do I have to explain why? to keep valid use of your type in hash-based containers likeDictionary
). You already know how to do the comparison itself. Only you forgot to compare list instances tonull
. Do it, too, otherwise your implementation is incorrect. Twonull
values comparison should return true.
Also, don''t forget to useobject.ReferencesEquals
, not "==" in your implementations, by two reasons: 1) if you implement "==", you would get into infinite recursion if "==" uses "==" in its implementation; 2) if two lists are equal as references, there is no point to check up list members — list instances are already equal.
—SA
这篇关于通用列表的相等比较.的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!