【问题标题】:List IndexOf return -1 even though there's a matching object c#即使有匹配的对象 c#,List IndexOf 也返回 -1
【发布时间】:2013-05-25 07:35:16
【问题描述】:

我有以下代码在List<ColorItem> 中查找ColorItem 对象的索引

//Get the index of the color item
var colorList = dialogViewModel.Items;
var colorItem = new ColorItem();
colorItem = sp.TileColorItem;
int index = colorList.IndexOf(colorItem);

即使列表中有匹配的对象,index 也始终返回 -1。我错过了什么?

【问题讨论】:

  • 有两个 colorItem 的值相同,但它们是不同的对象。一个在列表中,另一个不是
  • ColorItem 是你自己的班级吗?如果是这样,您可以通过覆盖 Equals... 使其工作,但我们需要上下文。

标签: c# list indexof


【解决方案1】:

List<T>.IndexOf 在列表中查找与您传递的值等于 的项目。默认情况下,对于类,相等只是对象标识——因此两个不同的对象被视为不相等,无论它们的字段是什么。但是,您可以通过覆盖 Equals 方法来更改此设置。

如果ColorItem 是你自己的类,你绝对可以通过覆盖Equals (和GetHashCode; List<T>.IndexOf 不使用它,但应该始终覆盖它以与@ 保持一致)来完成这项工作987654327@) 适当:

public sealed class ColorItem : IEquatable<ColorItem>
{
    private readonly string text;
    private readonly Color color;

    public string Text { get { return text; } }
    public Color Color { get { return color; } }

    public ColorItem(string text, Color color)
    {
        this.text = text;
        this.color = color;
    }

    public override bool Equals(object other)
    {
        return Equals(other as ColorItem);
    }

    public bool Equals(ColorItem otherItem)
    {
        if (otherItem == null)
        {
            return false;
        }
        return otherItem.Text == text && otherItem.Color == color;
    }

    public override int GetHashCode()
    {
        int hash = 19;
        hash = hash * 31 + (text == null ? 0 : text.GetHashCode());
        hash = hash * 31 + color.GetHashCode();
        return hash;
    }
}

现在IndexOf 应该可以正常工作了。

(我已经实施了IEquatable&lt;ColorItem&gt;,作为一般的良好做法。但这里并不是绝对必要的。)

【讨论】:

    【解决方案2】:

    您将colorItem 分配给sp.TileColorItem,它不在colorList 中。这就是为什么如果你调用colorList.IndexOf(colorItem) 它会返回-1。 你可能想使用这样的东西:

    int index;
    foreach (var item in colorList)
    {
        if (item.Text == sp.TileColorItem)
        {
            index = colorList.IndexOf(item);
        }
    }
    

    【讨论】:

    • 不。可能最简单的方法是遍历列表(使用循环计数器)并在颜色值相等时返回。
    • 不,我认为这不是最好的方法。如果将这些值视为可以将不同对象视为相等的值,则覆盖 Equals 以使 IndexOf 工作是有意义的。那时,您还可以将其用作字典键等。如果相关类不在我的控制之下,我只会像这样手动循环。
    • @JonSkeet 你可能是对的,但我相信对于初学者来说,循环List 来查找值比做一些棘手的事情(如覆盖)要容易得多。如果项目很小,则无需覆盖ColorItem类的Equals方法(可以是第三方框架的一部分)
    • @AndreyGordeev:而我认为值得解释正在发生的事情,并且至少给出选择。否则 OP 会认为他们不能做他们想做的事,并且当IndexOf 为其他类工作时很容易混淆。即使您打算循环,我也可能不会然后使用IndexOf再次循环,而是使用计数器。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-17
    • 2017-04-03
    • 2017-11-16
    • 1970-01-01
    • 2021-04-02
    • 1970-01-01
    相关资源
    最近更新 更多