Не удалось сравнить 2 объекта в массиве (сравнить с наследованием и универсальным) - PullRequest
3 голосов
/ 18 января 2011

Ситуация такова, что у меня есть 2 класса (один базовый класс и один производный класс, который наследует от базового класса).Оба класса реализуют метод CompareTo, поэтому я могу просто отсортировать список.

Базовый класс содержит следующие значения:

day, month  and year

Производный класс наследует эти 3 и добавляет еще 2:

hours and minutes

Проблема в том, что, когда я добавляю объекты Date и DateTime в список, он сортируется только по месяцам и годам.

Объект DateTime, который содержит (день, месяц, год, часы и минуты), только правильно сортирует базовые свойства, где часы и минуты не сортируются вообще.

Но когда, когда язакомментируйте все объекты Date и только добавьте объекты DateTime, вся сортировка выполнена правильно ...

Я получаю сообщение об ошибке "невозможно сравнить 2 объекта в массиве", когда я использую Virtual в базовом методе и override в производном запросе (по методам CompareTo)

Код:

Program.cs:

    List<Date> slDate = new List<Date>();

    slDate.Add(new Date(1, 2, 2011));
    slDate.Add(new Date(06, 01, 2000));

    slDate.Add(new DateTijd(10, 11, 2011, 5, 20));              
    slDate.Add(new DateTijd(8, 11, 2011, 20, 01));
    slDate.Add(new DateTijd(8, 11, 2011, 20, 30));


    slDate.Sort();

    for (int i = 0; i < slDate.Count; i++)
    {
        Console.WriteLine("{0}", slDate[i].ToString());
    }

Date.cs (базовый класс):

    //Constructor
    public Date(int d, int m, int j)
    {
      // .....
    }


    public virtual int CompareTo(Date d)
    {
        int res;

        res = this.Year.CompareTo(d.Year); //Year is a property
        if (res != 0) return res;

        res = this.Month.CompareTo(d.Month);
        if (res != 0) return res;

        res = this.Day.CompareTo(d.Day);
        if (res != 0) return res;

        return 0;
    }

}/*Date*/

DateTime.cs (производный класс):

    //Constructor
    public DateTime(int d, int m, int j, int h, int min): base(d, m, j)
    {
        //....
    }

    class DateTime: Date //derived class
    {
        //code ....

        public override int CompareTo(Date d) 
        {
            DateTime dt = (DateTime)d;
            int res;

            res = this.Hours.CompareTo(dt.Hours);
            if (res != 0) return res;

            res = this.Minutes.CompareTo(dt.Minutes);
            if (res != 0) return res;

            return 0; 
        }

    }

Ответы [ 2 ]

0 голосов
/ 18 января 2011

Во-первых, базовый класс должен реализовывать IComparable.Во-вторых, ваш подкласс пытается привести Date к DateTime (не всегда так).

public override int CompareTo(object obj) 
{
   var comparison = base.CompareTo(obj);
   if(comparison == 0 && obj is DateTime)
   {
      DateTime dt = (DateTime)obj;
      int res;

      res = this.Hours.CompareTo(dt.Hours);
      if (res != 0) return res;

      res = this.Minutes.CompareTo(dt.Minutes);
      if (res != 0) return res;

      return 0; 
    }
    return comparison;
}

Итак, мы выполняем сравнение базового класса.Если он определяет, что они равны, и мы имеем дело с датой и временем, то нам нужно дальнейшее сравнение.В противном случае просто верните базовое значение

Пример полиморфизма для комментария:

 public int DoCompare(Date firstDate, Date secondDate)
 {
    int res;

    res = firstDate.Year.CompareTo(secondDate.Year); //Year is a property
    if (res != 0) return res;

    res = firstDate.Month.CompareTo(secondDate.Month);
    if (res != 0) return res;

    res = firstDate.Day.CompareTo(secondDate.Day);
    if (res != 0) return res;

    return 0;
 }

Мы можем использовать эту функцию следующим образом:

var test = DoCompare(new DateTime(8,11,2011,20,30), new Date(1, 2, 2011));

Обратите внимание, мы только что прошлив DateTime, где функция взяла дату.Мы можем сделать это, потому что нам гарантировано, что DateTime будет иметь все функции и свойства, которые имеет Date (и многое другое ... но сейчас нам не нужны дополнительные функции).

Теперь посмотрите на эту функцию:

public int DoCompareDateTimes(DateTime firstDate, DateTime secondDate)
{
 int res;

 res = firstDate.Year.CompareTo(secondDate.Year); //Year is a property
 if (res != 0) return res;

 res = firstDate.Month.CompareTo(secondDate.Month);
 if (res != 0) return res;

 res = firstDate.Day.CompareTo(secondDate.Day);
 if (res != 0) return res;

 res = this.Hours.CompareTo(dt.Hours);
 if (res != 0) return res;

 res = this.Minutes.CompareTo(dt.Minutes);
 if (res != 0) return res;

 return 0;
}

var test = DoCompareDateTimes(new DateTime(8,11,2011,20,30), new Date(1, 2, 2011));

Мы не можем этого сделать.Функция ожидает объект DateTime, но мы передали Date (который не может быть приведен к DateTime, потому что DateTime имеет функции Date, которых нет)

0 голосов
/ 18 января 2011

Решено путем реализации класса Date: Icomparable<Date>

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...