Reputation: 343
I'm writing a C# application where I populate a DataGridView
with a list of objects of type Airport
. 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>
.
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
. I don't really know why. Is it because of my .toString()
overrided method? Because I need it to display the full Airport name on my DataGridView
of Flight methods.
My Airport
and Flight
classes are defined as follows:
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;
}
}
Upvotes: 4
Views: 8573
Reputation: 157136
You are creating a new instance before trying to delete it. Matching using object.Equals
will be done by reference. 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.
public override bool Equals(object o)
{
return o is Airport && ((Airport)o).id == this.id;
}
public override int GetHashCode()
{
return this.id.GetHashCode();
}
Upvotes: 7
Reputation: 54811
You need to override Equals
and GetHashCode
as Patrick has said, this is how I would do it:
Refer to https://msdn.microsoft.com/en-us/library/vstudio/336aedhh%28v=vs.100%29.aspx for more info.
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 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
}
}
Upvotes: 1
Reputation: 922
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
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();
}
Upvotes: 0