简体   繁体   English

比较参考?

[英]Compare by reference?

When working with the List class from System.Collections.Generic, methods like Contains or IndexOf will compare the passed reference's object using either the Equals method implemented from IEquatable, or the overridden Equals method provided by the Object class. 使用System.Collections.Generic中的List类时,Contains或IndexOf等方法将使用IEquatable实现的Equals方法或Object类提供的重写Equals方法来比较传递的引用对象。 If Object.Equals is not overridden, it will check whether the passed reference points to the same object as itself. 如果未覆盖Object.Equals,它将检查传递的引用是否指向与其自身相同的对象。

My question is: Is there a way of making List compare by reference if Equals is overridden? 我的问题是:如果等于被覆盖,是否有一种方法可以通过引用进行List比较? The code below will remove the item from the list: 下面的代码将从列表中删除该项:

class Program
{
    static void Main(string[] args)
    {    
        var s1 = new SomeClass() { A = 5 };
        var s2 = new SomeClass() { A = 5 };
        var list = new List<SomeClass>();
        list.Add(s1);
        list.Remove(s2); // s1 will get removed, even though s2 has been 
                         // passed, because s1's Equals method will return true.

    }
}

class SomeClass
{
    public int A { get; set; }

    public override bool Equals(object obj)
    {
        SomeClass s = obj as SomeClass;
        if (s == null)
        {
            return false;
        }
        else
        {
            return s.A == this.A;
        }
    }   
}

Let's say I'm unable to remove SomeClass' implementation of Equals, is there a way of making List compare by reference instead of value? 假设我无法删除SomeClass的Equals实现,有没有办法通过引用而不是值来进行List比较?

You can use List.RemoveAll and in your predicate, compare the items with Object.ReferenceEquals . 您可以使用List.RemoveAll并在谓词中将项目与Object.ReferenceEquals进行比较。

list.RemoveAll(item => object.ReferenceEquals(item, s2));

The code did successfully remove the 1 items when debugging from Visual Studio 2010 Express. 从Visual Studio 2010 Express调试时,代码成功删除了1个项目。

Austin's solution is simple and work. 奥斯汀的解决方案很简单,也很有效。 But here are two generic extension methods as well: 但是这里有两个通用的扩展方法:

items.RemoveAllByReference(item);

public static void RemoveAllByReference<T>(this List<T> list, T item)
{
    list.RemoveAll(x=> object.ReferenceEquals(x, item));
}

public static bool RemoveFirstByReference<T>(this List<T> list, T item)
{
    var index = -1;
    for(int i = 0; i< list.Count; i++)
        if(object.ReferenceEquals(list[i], item))
        {
            index = i;
            break;
        }
    if(index == -1)
        return false;

    list.RemoveAt(index);
    return true;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM