【问题标题】:Problems comparing objects using IComparable使用 IComparable 比较对象时出现问题
【发布时间】:2012-04-25 11:20:00
【问题描述】:

这是我正在尝试使用的一些代码。如果一组中的项目与另一组中的项目不匹配,则将 0 添加到所有比较项目的列表中。如果最终列表不包含除 0 以外的任何其他值,则表示第一个集合中的项目在第二个集合中根本不存在。由于某种原因,我总是在结果列表中得到错误的值,所以一定是某个地方有错误,只是我似乎找不到它。

    public class CompareItem : IComparable
    {
        public string CustId { get; set; }
        public string TechId { get; set; }

        public CompareItem(string custId, string techId)
        {
            CustId = custId;
            TechId = techId;
        }

        public int CompareTo(object obj)
        {
            CompareItem Temp = (CompareItem)obj;
            if (this.CustId != Temp.CustId || this.TechId != Temp.TechId)
            {
                return 0;
            }
            else
            {
                return 1;
            }
        }
    }

    static void Main(string[] args)
    {
        List<CompareItem> LeftCompareSet = new List<CompareItem>();

        LeftCompareSet1.Add(new CompareItem("0000", "0001"));
        LeftCompareSet1.Add(new CompareItem("0001", "0001"));
        LeftCompareSet1.Add(new CompareItem("0002", "0002"));
        LeftCompareSet1.Add(new CompareItem("0003", "0003"));
        LeftCompareSet1.Add(new CompareItem("0002", "0004"));

        List<CompareItem> RightCompareSet = new List<CompareItem>();

        RightCompareSet1.Add(new CompareItem("0005", "0005"));
        RightCompareSet1.Add(new CompareItem("0004", "0004"));
        RightCompareSet1.Add(new CompareItem("0003", "0003"));
        RightCompareSet1.Add(new CompareItem("0002", "0002"));
        RightCompareSet1.Add(new CompareItem("0006", "0002"));

        int state = 0;

        List<int> tlc = new List<int>();
        List<int> trc = new List<int>();

        foreach (CompareItem lc in LeftCompareSet)
        {
            foreach (CompareItem rc in RightCompareSet)
            {
                state = lc.CompareTo(rc);
                if (state == 0)
                {
                    tlc.Add(0);
                }
                else
                { 
                    tlc.Add(1);
                }
            }

            if (tlc.Contains(1))
            {
                Console.WriteLine("Cust: " + lc.CustId + ", Tech: " + lc.TechId + ", Not missing");
            }
            else
            {
                Console.WriteLine("Cust: " + lc.CustId + ", Tech: " + lc.TechId + ", Missing");
            }
        }

        foreach (CompareItem rc in RightCompareSet)
        {
            foreach (CompareItem lc in LeftCompareSet)
            {
                state = rc.CompareTo(lc);
                if (state == 0)
                {
                    trc.Add(0);
                }
                else
                {
                    trc.Add(1);
                }
            }

            if (trc.Contains(1))
            {
                Console.WriteLine("Cust: " + rc.CustId + ", Tech: " + rc.TechId + ", Not missing");
            }
            else
            {
                Console.WriteLine("Cust: " + rc.CustId + ", Tech: " + rc.TechId + ", Missing");
            }
        }
    }

【问题讨论】:

    标签: c# object compare icomparable


    【解决方案1】:

    您的CompareTo 错误。如果两个对象相同,则返回 0,如果一个小于另一个,则返回 -1,如果大于另一个,则返回 1。见here

    【讨论】:

    • 谢谢。因此,如果对象匹配,我将 return 1 更改为 return 0,但如果对象不匹配,我必须返回一些东西,而且我对对象的属性是否更大或更小不感兴趣。对不匹配的对象使用 1 似乎有效,除了第二个列表中的最后一项,它表示它包含在第一个列表中,事实并非如此。
    • 你应该改写你班级的EqualsGetHashCode,这样更有意义。
    【解决方案2】:

    我认为这种方法存在几个问题:

    1. 代码包含一个小错误:它必须是 LeftCompareSet 而不是 LeftCompareSet1

    2. 在 CompareTo 中,您没有检查对象的类型,如果使用错误的对象调用该方法,您会得到一个异常。

    3. 我认为您真正需要的是实现 Equals 方法: 公共覆盖布尔等于(对象obj) (不要忘记GetHashCode)

    4. 不确定您真正想要实现什么,可能设置操作更有帮助

    5. 你没有写出结果有什么问题,如果我执行你的代码,我会得到以下结果:

      • 客户:0000,技术:0001,失踪
      • 客户:0001,技术:0001,失踪
      • 客户:0002,技术:0002,没有丢失
      • 客户:0003,技术:0003,没有丢失
      • 客户:0002,技术:0004,没有丢失
      • 客户:0005,技术:0005,失踪

    【讨论】:

      【解决方案3】:

      您只想确认第一个列表中的项目是 存在于第二个列表中?

      如果我是对的,那么你已经走了很长一段路。 只需从一个列表中取出一个项目并检查它是否存在于第二个列表中

      示例:

      secondList.Exists(first[0]);

      它将返回布尔值。

      【讨论】:

      • 据我所知,您的建议仅适用于对象,不适用于对象属性。在这个例子中可能不明显,但我还需要比较属性值,所以对象只有部分不同。
      • 是的,你是对的 BTW Cust: 0002, Tech: 0004, Not Missing
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多