zcohen
zcohen

Reputation: 317

Except function doesn't work on a list that I got from xml file

I am trying to use IEnumerable.Except function in c# 4.0 to get the difference between two lists like this:

//Function to get only available rooms out of all rooms of the hotel...
public IEnumerable<Room> GetAvailableRooms(DateTime arrival, DateTime leaving)
        {
                //.....
                foreach (Room value in v)
                    room_list.Add(value);
                return (dal.GetAllRooms()).Except(room_list);                
        }

but the function doesn't work - it doesn't remove the items of room_list.

(I checked in debugging and room_list contains the desired values)

dal.GetAllRooms is a functions that gets all rooms from xml file in Data Access Layer.

I am sure that the problem is about xml because when I use my DAL implemention with lists (not xml) the same exact function works fine.

Upvotes: 0

Views: 239

Answers (2)

Mustafa
Mustafa

Reputation: 204

Implementation given by Daniel is correct when you are checking for equality. But in order to use Except() for a custom class you need to override the GetHashCode() method for your custom class. See below code snippet:

class Program
{
    static void Main()
    {
        ObservableCollection<A> one = new ObservableCollection<A>();
        ObservableCollection<A> two = new ObservableCollection<A>();

        one.Add(new A()
        {
            number = 1,
            name = "A"
        });

        one.Add(new A()
        {
            number = 2,
            name = "B"
        });

        two.Add(new A()
        {
            number = 1,
            name = "A"
        });


        ObservableCollection<A> three = new ObservableCollection<A>(one.Except(two));

    }
}

class A : IEquatable<A>
{
    public int number;
    public string name;

    public bool Equals(A other)
    {
        return (number == other.number && name == other.name);
        //throw new NotImplementedException();
    }

    public override int GetHashCode()
    {
        // Get the hash code for the Textual field if it is not null.

        int hashnumber = number == null ? 0 : number.GetHashCode();



        // Get the hash code for the Digital field.

        int hashname = name.GetHashCode();



        // Calculate the hash code for the object.

        return hashnumber ^ hashname;

    }
}

Here three will have the value as {2,"B"}.

Upvotes: 2

Daniel Hilgarth
Daniel Hilgarth

Reputation: 174399

Do you override Object.Equals in Room? Or do you implement IEquatable? If not, Except checks whether the references are the same and they are not, even if all values inside the instances are the same.

Example:

class Room
{
    public Room(int roomNumber) { RoomNumber = roomNumber; }
    public int RoomNumber { get; set; }
}

class Room2
{
    public Room2(int roomNumber) { RoomNumber = roomNumber; }
    public int RoomNumber { get; set; }

    public override bool Equals(object other)
    {
        var otherRoom = other as Room2;
        if(otherRoom == null)
            return false;

        return roomNumber == otherRoom.RoomNumber
    }
}


var room1a = new Room(404);
var room1b = new Room(404);

var room2a = new Room2(405);
var room2b = new Room2(405);

Assert.False(object.Equals(room1a, room1b));
Assert.True(object.Equals(room2a, room2b));

Upvotes: 1

Related Questions