通过参考比较?

发布于 2025-01-06 01:30:09 字数 1012 浏览 4 评论 0原文

使用 System.Collections.Generic 中的 List 类时,Contains 或 IndexOf 等方法将使用从 IEquatable 实现的 Equals 方法或 Object 类提供的重写的 Equals 方法来比较传递的引用的对象。如果Object.Equals没有被重写,它将检查传递的引用是否指向与其自身相同的对象。

我的问题是:如果覆盖 Equals,是否有办法使 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;
        }
    }   
}

假设我无法删除 SomeClass 的 Equals 实现,是否有一种方法可以使 List 通过引用而不是值进行比较?

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. If Object.Equals is not overridden, it will check whether the passed reference points to the same object as itself.

My question is: Is there a way of making List compare by reference if Equals is overridden?
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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

淡墨 2025-01-13 01:30:09

您可以使用 List.RemoveAll 并在谓词中将项目与 Object.ReferenceEquals

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

从 Visual Studio 2010 Express 进行调试时,代码确实成功删除了 1 项。

You can use List.RemoveAll and in your predicate, compare the items with Object.ReferenceEquals.

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

The code did successfully remove the 1 items when debugging from Visual Studio 2010 Express.

裸钻 2025-01-13 01:30:09

奥斯汀的解决方案既简单又有效。但这里还有两个通用的扩展方法:

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;
}

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文