[英]Object.Equals() method returns false on seemingly equal object
I'm writing a C# application where I populate a DataGridView
with a list of objects of type Airport
.我正在编写一个 C# 应用程序,在其中使用
Airport
类型的对象列表填充DataGridView
。 I'm currently writing the method to delete one after pressing a button.我目前正在编写按下按钮后删除一个的方法。
For reference dgvF
is a DataGridView
containing the flights List<Flights>
, I also have a dgvA for my airports List<Airports>
.仅供参考
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();
}
However, the if(delete.Equals(aO) || delete.Equals(aD))
and if (airports.Contains(delete))
lines never return true, I run the Application on debug mode and although at one point delete
is {"TIJ- Tijuana"}
and aD
is {"TIJ - Tijuana"}
the boolean operation still returns false
.但是,
if(delete.Equals(aO) || delete.Equals(aD))
和if (airports.Contains(delete))
行永远不会返回 true,我在调试模式下运行应用程序,尽管在某一时刻delete
是{"TIJ- Tijuana"}
{"TIJ - Tijuana"}
{"TIJ- Tijuana"}
和aD
是{"TIJ - Tijuana"}
布尔运算仍然返回false
。 I don't really know why.我真的不知道为什么。 Is it because of my
.toString()
overrided method?是因为我的
.toString()
覆盖方法吗? Because I need it to display the full Airport name on my DataGridView
of Flight methods.因为我需要它在 Flight 方法的
DataGridView
上显示完整的机场名称。
My Airport
and Flight
classes are defined as follows:我的
Airport
和Flight
类定义如下:
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
}
}
and和
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;
}
}
You are creating a new instance before trying to delete it.您在尝试删除之前创建了一个新实例。 Matching using
object.Equals
will be done by reference.使用
object.Equals
匹配将通过引用完成。 That means that the 'address pointer in memory' is checked against the 'address pointer in memory' of the new one.这意味着“内存中的地址指针”会根据新的“内存中的地址指针”进行检查。 That can never be true.
那永远不可能是真的。
You should override and implement Equals
and GetHashCode
in your class in order to influence the comparison.您应该在您的类中覆盖和实现
Equals
和GetHashCode
以影响比较。
public override bool Equals(object o)
{
return o is Airport && ((Airport)o).id == this.id;
}
public override int GetHashCode()
{
return this.id.GetHashCode();
}
You need to override Equals
and GetHashCode
as Patrick has said, this is how I would do it:正如帕特里克所说,您需要覆盖
Equals
和GetHashCode
,这就是我的做法:
Refer to https://msdn.microsoft.com/en-us/library/vstudio/336aedhh%28v=vs.100%29.aspx for more info.有关详细信息,请参阅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
}
}
Or if sealed
:或者如果
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
}
}
If the current instance is a reference type, the Equals(Object) method tests for reference equality, and a call to the Equals(Object) method is equivalent to a call to the ReferenceEquals method如果当前实例是引用类型,则 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.