开发者

Failed to compare 2 objects in the array (compare with inheritance and generic)

开发者 https://www.devze.com 2023-02-05 10:36 出处:网络
The situation is i have 2 classes (one base class and one derived class who inherits from the base class).

The situation is i have 2 classes (one base class and one derived class who inherits from the base class). Both classes implement the CompareTo method, so i can basicly sort the list.

The base class holds the following values:

day, month  and year

The derived class inherits those 3 and adds 2 more:

hours and minutes

The problem is when i add Date and DateTime objects in a list it only sorts properly on day month and year.

The DateTime object that holds (day , month, year, hours and minutes) only sorts the base properties properly, where the hours and minutes are not sorted at all.

But when when i comment all Date Objects and only add DateTime objects the entire sorting is done properly...

I am getting the error "cannot compare 2 objects in the array" when i use Virtual in the base method and override in the derived calss (on the CompareTo methods)

The code:

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 (base class):

    //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)开发者_C百科 return res;

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

        return 0;
    }

}/*Date*/

DateTime.cs (derived class):

    //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; 
        }

    }


Firstly, the base class needs to implement IComparable.
Secondly, your sub class is trying to cast a Date as a DateTime (not always the case).

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

So, we perform the base class' comparison. If it determines they're equal, and we're dealing with a date time, then we need further comparison. Otherwise, just return the base value

Example of polymorphism for the comment:

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

We can use that function like this:

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

Note we just passed in a DateTime where the function took a Date. We can do this because we are guaranteed that DateTime will have all the functions and properties that Date has (and more.. but for now we don't care about the additional functionality).

Now look at this function:

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

We can't do this. The function is expecting an object of DateTime, but we've passed in a Date (which cannot be cast to a DateTime because DateTime has features Date does not)


Solved by implementing class Date: Icomparable<Date>

0

精彩评论

暂无评论...
验证码 换一张
取 消