通用列表的相等比较. [英] Equalitable comparison of generic lists.

查看:80
本文介绍了通用列表的相等比较.的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个例程,用于比较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 implement IEqualitable, which is generally used to compare objects of different types.

Your task is much more simple. Derive a generic type from the type System.Collections.Generic.List — it is not sealed. In the derived class, override object.Equals and define operators "!=" and "==". It will also require overridden object.GetHashCode (do I have to explain why? to keep valid use of your type in hash-based containers like Dictionary). You already know how to do the comparison itself. Only you forgot to compare list instances to null. Do it, too, otherwise your implementation is incorrect. Two null values comparison should return true.

Also, don''t forget to use object.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屋!

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