繁体   English   中英

Object.Equals() 方法在看似相等的对象上返回 false

[英]Object.Equals() method returns false on seemingly equal object

我正在编写一个 C# 应用程序,在其中使用Airport类型的对象列表填充DataGridView 我目前正在编写按下按钮后删除一个的方法。

仅供参考dgvF是一个DataGridView包含flights List<Flights> ,我也有一个dgvA我的airports List<Airports>

private void bajaAeropuerto_Click(object sender, EventArgs e)
{
    String c = city.Text;
    String id = idAirport.Text;

    Airport delete = new Airport(c, id);

    //Select all Flights which reference the "delete" airport
    foreach (DataGridViewRow row in listaVuelos.Rows)
    {
        Flight v = (Flight)row.DataBoundItem;
        Airport aO = v.fromCity;
        Airport aD = v.toCity;

        if(delete.Equals(aO) || delete.Equals(aD))
        {
            dgvF.MultiSelect = true;
            row.Selected = true;
        }
    }

    if (airports.Contains(delete))
    {
        airports.Remove(delete);
    }
    else
    {
        //show message airport doesn't exist
    }

    dgvAirports.Update();
    dgvAirports.Refresh();
}

但是, if(delete.Equals(aO) || delete.Equals(aD))if (airports.Contains(delete))行永远不会返回 true,我在调试模式下运行应用程序,尽管在某一时刻delete{"TIJ- Tijuana"} {"TIJ - Tijuana"} {"TIJ- Tijuana"}aD{"TIJ - Tijuana"}布尔运算仍然返回false 我真的不知道为什么。 是因为我的.toString()覆盖方法吗? 因为我需要它在 Flight 方法的DataGridView上显示完整的机场名称。

我的AirportFlight类定义如下:

class Airport
{
    public String city{ get; set; }
    public String id { get; set; }

    public Airport(String ciudad, String id)
    {
        this.city = city;
        this.id = id;
    }

    public override string ToString()
    {
        return id + "- " + city; //Ej. MX- Mexico City
    }
}

class Flight
{
    public String id { get; set; }
    public Airport fromCity{ get; set; }
    public Airport toCity { get; set; }
    public int price{ get; set; }

    public Flight(String id, Aeropuerto origen, Aeropuerto destino, int precio)
    {
        this.id = id;
        this.fromCity = origen;
        this.toCity = destino;
        this.price= precio;
    }
}

您在尝试删除之前创建了一个新实例。 使用object.Equals匹配将通过引用完成。 这意味着“内存中的地址指针”会根据新的“内存中的地址指针”进行检查。 那永远不可能是真的。

您应该在您的类中覆盖和实现EqualsGetHashCode以影响比较。

public override bool Equals(object o)
{
    return o is Airport && ((Airport)o).id == this.id;
}

public override int GetHashCode()
{
    return this.id.GetHashCode();
}

正如帕特里克所说,您需要覆盖EqualsGetHashCode ,这就是我的做法:

有关详细信息,请参阅https://msdn.microsoft.com/en-us/library/vstudio/336aedhh%28v=vs.100%29.aspx

class Airport
{
    ...

    public override bool equals(Object obj)
    {
        //types must be the exactly the same for non-sealed classes
        if (obj == null || obj.GetType() != GetType()) 
          return false;
        return equals((AirPort)obj);
    }

    private bool equals(AirPort other)
    {
        if (other == null)
          return false;
        return other.id == id; //only id should be needed if unique
    }

    public override int GetHashCode()
    {
        return id.GetHashCode(); //again, only id needed
    }
}

或者如果sealed

sealed class Airport
{
    ...

    public override bool equals(Object obj)
    {
        return equals(obj as AirPort);
    }

    public bool equals(AirPort other)
    {
        if (other == null)
          return false;
        return other.id == id; //only id should be needed if unique
    }

    public override int GetHashCode()
    {
        return id.GetHashCode(); //again, only id needed
    }
}

如果当前实例是引用类型,则 Equals(Object) 方法测试引用相等性,调用 Equals(Object) 方法等效于调用 ReferenceEquals 方法

  public override bool Equals(Object obj) {
  // Perform an equality check on two rectangles (Point object pairs). 
      if (obj == null || GetType() != obj.GetType()) 
         return false;
       Airport r = (Airport)obj;
      return fromCity.Equals(r.fromCity) && toCity .Equals(r.toCity );
  }

  public override int GetHashCode() {
     return Tuple.Create(fromCity, toCity ).GetHashCode();
  }

暂无
暂无

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

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