Проблемы со сравнением объектов с использованием IComparable

Вот код, который я пытаюсь заставить работать. Если элемент в одном наборе не соответствует элементу в другом наборе, 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");
            }
        }
    }

person Willem    schedule 25.04.2012    source источник


Ответы (3)


Ваш CompareTo неверен. Он должен возвращать 0, если два объекта одинаковы, -1, если один меньше другого, и 1, если он больше. См. здесь

person zmbq    schedule 25.04.2012
comment
Спасибо за это. Поэтому я меняю return 1 на return 0, если объекты совпадают, но я должен что-то вернуть, если объекты не совпадают, и меня не интересует, больше или меньше свойства объекта. Использование 1 для несовпадающих объектов, кажется, работает, за исключением последнего элемента во втором списке, он говорит, что он содержится в первом списке, что не так. - person Willem; 25.04.2012
comment
Вместо этого вы должны переопределить Equals и GetHashCode вашего класса, это имеет больше смысла. - person zmbq; 25.04.2012

Я думаю, что в этом подходе есть несколько проблем:

  1. код содержит небольшую ошибку: это должен быть LeftCompareSet вместо LeftCompareSet1

  2. В CompareTo вы пропускаете проверку типа объекта, если метод вызывается с неправильным объектом, вы получаете исключение.

  3. Я думаю, что вам действительно нужно реализовать метод Equals: public override bool Equals(object obj) (не забудьте GetHashCode)

  4. Не уверен, чего вы действительно хотите достичь, возможно, операция set будет более полезной.

  5. Вы не написали, что не так с результатами, если я выполняю ваш код, я получаю следующий результат:

    • Cust: 0000, Tech: 0001, Missing
    • Кастом: 0001, Техник: 0001, Пропал без вести
    • Кастом: 0002, Техник: 0002, Не пропало
    • Кастом: 0003, Техник: 0003, Не пропало
    • Кастом: 0002, Техник: 0004, Не пропало
    • Кастом: 0005, Техник: 0005, Пропал без вести
person FrankE    schedule 25.04.2012

Вы просто хотите подтвердить, что элементы в первом списке существуют во втором списке?

Если я прав, то вы прошли долгий путь. просто возьмите элемент из одного списка и проверьте, существует ли он во втором списке или нет

пример :

второйСписок.Существует(первый[0]);

он вернет логическое значение.

person Red    schedule 25.04.2012
comment
Насколько я знаю, ваше предложение работает только с объектами, а не со свойствами объектов. В этом примере это может быть неочевидно, но мне также нужно сравнить значения свойств, поэтому объекты отличаются лишь частично. - person Willem; 25.04.2012
comment
Да, вы правы, кстати, Cust: 0002, Tech: 0004, Not Missing ‹= здесь проблема, верно? - person Red; 25.04.2012