首页 \ 问答 \ LINQ.Distinct IEquatable对象不起作用(LINQ.Distinct on IEquatable object doesn't work)

LINQ.Distinct IEquatable对象不起作用(LINQ.Distinct on IEquatable object doesn't work)

我有一个继承自IEquatable <>的基类的对象。 到目前为止一切都很好,它适用于继承相同基类的其他对象。 但我在课堂上“RoomType”,当我使用“Attrbiutes”属性时似乎有问题。 下面你会看到我希望得到其他输出的类和测试。

我将问题缩小到RoomType.GetHashCode(),当我评论“SafeHashCode(Attributes)”时,返回预期的结果。

测试:

 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
    }

房型:

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();
}

更新我能够通过在SafeHashCode(T x)中添加以下代码来解决它

 IEnumerable<object> xEnumerable = x as IEnumerable<object>;
        if (xEnumerable != null)
            return xEnumerable.Aggregate(17, (acc, item) => acc * 19 + SafeHashCode(item));

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));

原文:https://stackoverflow.com/questions/43232457
更新时间:2023-06-01 14:06

最满意答案

cellForRowAtIndexPath方法中像这样设置按钮文本首先删除它

cell.dbColumnOrder.titleLabel?.text = column.order

替换它

cell.dbColumnOrder.setTitle("\(column.order)", for: .normal)

还有一件事需要增加cell.dbColumnOrder宽度。

希望它有效


In cellForRowAtIndexPath method Set button text like this way First remove this

cell.dbColumnOrder.titleLabel?.text = column.order

Replace this

cell.dbColumnOrder.setTitle("\(column.order)", for: .normal)

And one more thing you need to increase cell.dbColumnOrder width.

Hope it works

相关问答

更多

相关文章

更多

最新问答

更多
  • h2元素推动其他h2和div。(h2 element pushing other h2 and div down. two divs, two headers, and they're wrapped within a parent div)
  • 创建一个功能(Create a function)
  • 我投了份简历,是电脑编程方面的学徒,面试时说要培训三个月,前面
  • PDO语句不显示获取的结果(PDOstatement not displaying fetched results)
  • Qt冻结循环的原因?(Qt freezing cause of the loop?)
  • TableView重复youtube-api结果(TableView Repeating youtube-api result)
  • 如何使用自由职业者帐户登录我的php网站?(How can I login into my php website using freelancer account? [closed])
  • SQL Server 2014版本支持的最大数据库数(Maximum number of databases supported by SQL Server 2014 editions)
  • 我如何获得DynamicJasper 3.1.2(或更高版本)的Maven仓库?(How do I get the maven repository for DynamicJasper 3.1.2 (or higher)?)
  • 以编程方式创建UITableView(Creating a UITableView Programmatically)
  • 如何打破按钮上的生命周期循环(How to break do-while loop on button)
  • C#使用EF访问MVC上的部分类的自定义属性(C# access custom attributes of a partial class on MVC with EF)
  • 如何获得facebook app的publish_stream权限?(How to get publish_stream permissions for facebook app?)
  • 如何防止调用冗余函数的postgres视图(how to prevent postgres views calling redundant functions)
  • Sql Server在欧洲获取当前日期时间(Sql Server get current date time in Europe)
  • 设置kotlin扩展名(Setting a kotlin extension)
  • 如何并排放置两个元件?(How to position two elements side by side?)
  • 如何在vim中启用python3?(How to enable python3 in vim?)
  • 在MySQL和/或多列中使用多个表用于Rails应用程序(Using multiple tables in MySQL and/or multiple columns for a Rails application)
  • 如何隐藏谷歌地图上的登录按钮?(How to hide the Sign in button from Google maps?)
  • Mysql左连接旋转90°表(Mysql Left join rotate 90° table)
  • dedecms如何安装?
  • 在哪儿学计算机最好?
  • 学php哪个的书 最好,本人菜鸟
  • 触摸时不要突出显示表格视图行(Do not highlight table view row when touched)
  • 如何覆盖错误堆栈getter(How to override Error stack getter)
  • 带有ImageMagick和许多图像的GIF动画(GIF animation with ImageMagick and many images)
  • USSD INTERFACE - > java web应用程序通信(USSD INTERFACE -> java web app communication)
  • 电脑高中毕业学习去哪里培训
  • 正则表达式验证SMTP响应(Regex to validate SMTP Responses)