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

时间:2015-04-13 07:25:21

标签: c#

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

参考dgvFDataGridView,其中包含flights List<Flights>,我的airports List<Airports>也有一个dgvA。

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"} aD{"TIJ - Tijuana"} } {是false布尔运算仍返回.toString()。我真的不知道为什么。是因为我的DataGridView覆盖方法?因为我需要它在我的Airport飞行方法上显示完整的机场名称。

我的Flightclass 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;
    }
}

{{1}}

3 个答案:

答案 0 :(得分:6)

您正在创建新实例以便删除。使用object.Equals进行匹配将通过引用完成。这意味着内存中的地址指针&#39;根据内存中的&#39;地址指针进行检查&#39;新的。这永远不会成真。

您应该在班级中覆盖并实施EqualsGetHashCode,以便影响比较。

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

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

答案 1 :(得分:1)

你需要覆盖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
    }
}

答案 2 :(得分:0)

如果当前实例是引用类型,则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();
  }