I've an object that inherites from a base class that inherits from IEquatable<>. So far so good and it works for other objects that inherit the same base class. But I have on class "RoomType" where there seems to be a problem when I use the "Attrbiutes" property. Below you see the classes and a test where I expect other output that given.
I narrowed the problem down to something with the RoomType.GetHashCode(), when I comment "SafeHashCode(Attributes)" the expected result is returned.
Test:
 private static void QuickTest()
    {
        RoomType[] rooms = new RoomType[] {
            new RoomType {
                Attributes = new [] { "a", "b,"c"},
            },
            new RoomType
            {
                Attributes = new [] { "a", "b","c"},
            }
        };
        List<RoomType> result = rooms.Distinct().ToList();
        //result contains 2 items, I was expecting 1
    }
RoomType:
public class RoomType : EntityBase
{
    public string OriginalRoomCode { get; set; }
    public Enum.RoomType RoomCode { get; set; }
    public IEnumerable<string> Attributes { get; set; }
    public override bool Equals(object obj)
    {
        RoomType other = obj as RoomType;
        if (other != null)
            return Equals(other);
        return false;
    }
    public override bool Equals(EntityBase obj)
    {
        RoomType y = (RoomType)obj;
        return SafeEqual(OriginalRoomCode, y.OriginalRoomCode) &&
            SafeEqual(RoomCode, y.RoomCode) &&
            SafeEqual(Attributes,y.Attributes);
    }
    public override int GetHashCode()
    {
        unchecked
        {
            return SafeHashCode(OriginalRoomCode) ^
                   SafeHashCode(RoomCode) ^ 
                   SafeHashCode(Attributes);
        }
    }
    public override object Clone()
    {
        return new RoomType
        {
            RoomCode = (Enum.RoomType)SafeClone(RoomCode),
            OriginalRoomCode = (string)SafeClone(OriginalRoomCode),
            Attributes = (IEnumerable<string>)SafeClone(Attributes)
        };
    }
}
EntityBase:
public abstract class EntityBase : IEquatable<EntityBase>, ICloneable
{
    public bool SafeEqual<T>(T x, T y)
    {
        bool isXDefault = EqualityComparer<T>.Default.Equals(x, default(T));
        bool isYDefault = EqualityComparer<T>.Default.Equals(y, default(T));
        if (isXDefault && isYDefault)
            return true;
        if (isXDefault != isYDefault)
            return false;
        if (x is EntityBase)
            return x.Equals(y);
        IEnumerable<object> xEnumerable = x as IEnumerable<object>;
        IEnumerable<object> yEnumerable = y as IEnumerable<object>;
        if (xEnumerable != null && yEnumerable != null)
        {
            foreach (var yItem in yEnumerable)
            {
                bool match = false;
                foreach (var xItem in xEnumerable)
                {
                    if(SafeEqual(xItem, yItem))
                    {
                        match = true;
                        break;
                    }                        
                }
                if (!match)
                    return false;
            }
            return true;
        }
        return x.Equals(y);
    }
    public int SafeHashCode<T>(T x)
    {
        if (EqualityComparer<T>.Default.Equals(x, default(T)))
            return 0;
        return x.GetHashCode();
    }
    public object SafeClone<T>(T x)
    {
        //if x is null or default value
        if (EqualityComparer<T>.Default.Equals(x, default(T)))
            return default(T);
        //if x is of type EntityBase call clone()
        if (x is EntityBase)
            return (x as EntityBase).Clone();
        //else the type is a default type return the value
        return x;
    }
    public abstract bool Equals(EntityBase other);
    public override abstract int GetHashCode();
    public abstract override bool Equals(object obj);
    public abstract object Clone();
}
Update I was able to fix it by adding the following code inside SafeHashCode(T x)
 IEnumerable<object> xEnumerable = x as IEnumerable<object>;
        if (xEnumerable != null)
            return xEnumerable.Aggregate(17, (acc, item) => acc * 19 + SafeHashCode(item));
 
     
     
    