3

I am sorry if this is duplicate. Please point to correct question.

I have a class called MyDate like below

public class MyDate
{
    private SqlDateTime m_dateTime;

    public MyDate(DateTime dateTime)
    {
       if (DateTime.Compare(dateTime, (DateTime)SqlDateTime.MinValue) <= 0)
            m_dateTime = SqlDateTime.MinValue;
        else
            m_dateTime = dateTime;
    }

    public string MMDDYYYYHHMMSS
    {
       get
         {
            if(m_dateTime > SqlDateTime.MinValue)
                return m_dateTime.Value.ToString("MM/dd/yyyy hh:mm:ss tt");
            else
                return String.Empty;
         }
    }
}

I have class called MyEvent like below

public class MyEvent
{
  public int EventId{get;set;}
  public MyDate StartDate{get;set;}
}

I have collection of MyEvent like

List<MyEvent> myEvents. 

Now I need to sort myEvents in descending order of StartDate. The problem I have is I cannot add IComparable or change MyDate since it is written by other team and I just refer dll. I donot have control on MyDate code. Can anybody help me how I can do. I created a new comparer class that implements IComparer but unable to understand how to use it and sort myEvents.

**UPDATE 1 **

Thank you very much for Alexei, Ehsan and Dave for helping me out. I tried Dave's answer and it worked. I was trying to do it in more better way so that there is no need to add any new properties. I didnot try Ehsan way of using StringDateComparer but it helped me to understand how I can use Comparer in Order linq statements. At last as pointed by Alexei I did like below

**UPDATE 2 **

Sometimes I am getting empty string for e2.StartDate.MMDDYYYYHHMMSS and/or e2.StartDate.MMDDYYYYHHMMSS so I changed my code like below

myEvents.Sort(
                delegate(MyEvent e1, MyEvent e2)
                 {
                     DateTime dt1;
                     DateTime dt2;
                     DateTime.TryParse(e1.StartDateTime.MMDDYYYYHHMMSS, out dt1);
                     DateTime.TryParse(e2.StartDateTime.MMDDYYYYHHMMSS, out dt2);

                     return dt2.CompareTo(dt1); // descending
                     //return dt1.CompareTo(dt2); // ascending
                    }
            );
Ziggler
  • 3,361
  • 3
  • 43
  • 61
  • it not exact duplicate, OP scenario is different – Ehsan Sajjad Sep 15 '15 at 18:23
  • 2
    A class that takes a `DateTime` converts to a `SqlDateTime` and only exposes a `string`? Your real problem is this other team. – juharr Sep 15 '15 at 18:23
  • You've obviously seen what I believe is [duplicate](http://stackoverflow.com/questions/3309188/how-to-sort-a-listt-by-a-property-in-the-object) of you question since it first link to search for title of your post (https://www.bing.com/search?q=C%23+%3A+Sort+list+on+custom+property). Please clarify why solutions suggested there did not work (including custom comparer) so it is clear that this post is not duplicate. – Alexei Levenkov Sep 15 '15 at 18:24
  • My scenario is different. In MyDate I donot have any DateTime property. So I cannot use any sort or order by methods. I was trying to avoid adding extra property in MyEvent class. I tried IComparer. All the examples I saw just jumped directly using OrderBy linq statement without showing how IComparer implementation came into picture... – Ziggler Sep 15 '15 at 18:29
  • @Ziggler http://stackoverflow.com/a/3309397/477420 shows perfect example of custom comparer... – Alexei Levenkov Sep 15 '15 at 18:32

2 Answers2

3

This might be inefficient, but you could add a DateTime property to your MyEvent class that converts StartDate to a DateTime and sort on that:

public class MyEvent
{
    public int EventId{get;set;}
    public MyDate StartDate{get;set;}
    public DateTime MyStartDate { get { return DateTime.Parse(StartDate.MMDDYYYYHHMMSS); } }
}

var sorted = myEvents.OrderByDescending(e => e.MyStartDate);

Alternatively, you could make the class immutable and do the conversion when instantiating it:

public class MyEvent
{
    public MyEvent(int eventId, MyDate startDate)
    {
        EventId = eventId;
        StartDate = startDate;
        MyStartDate = DateTime.Parse(StartDate.MMDDYYYYHHMMSS);
    }

    public int EventId{get; private set;}
    public MyDate StartDate{get; private set;}
    public DateTime MyStartDate { get; private set; }
}
Dave Zych
  • 21,581
  • 7
  • 51
  • 66
  • 1
    better yet would be to set the `MyStartDate` property when creating a `MyEvent` and making `MyEvent` immutable.. – juharr Sep 15 '15 at 18:20
  • Thank you very much. I tried it and it worked. I was trying to do it in more better way so that there is no need to add any new properties – Ziggler Sep 15 '15 at 19:04
3

You can write it with Linq OrderyBy() or OrderByDescending method according to your need this way:

var outputDate = myEvents.OrderByDescending(x=>
                          {
                           DateTime parsedDate;
                           return DateTime.TryParseExact(x.StartDate, "MM/dd/yyyy hh:mm:ss tt", CultureInfo.InvariantCulture, DateTimeStyles.None, out parsedDate) ? parsedDate : DateTime.MinValue;
                          });

or proper way would be to create a custom IComparer for it:

public class StringDateComparer : IComparer<string>
{

    public int Compare(string date1, string date2)
    {
        DateTime parsedDate1;
        DateTime.TryParseExact(date1, "MM/dd/yyyy hh:mm:ss tt", CultureInfo.InvariantCulture, DateTimeStyles.None, out parsedDate1);


        DateTime parsedDate2;
        DateTime.TryParseExact(date2, "MM/dd/yyyy hh:mm:ss tt", CultureInfo.InvariantCulture, DateTimeStyles.None, out parsedDate2);



        if (parsedDate1 < parsedDate2)
            return -1;
        if (parsedDate1 > parsedDate2)
            return 1;


        return 0;
    }
}

and now call OrderByDescending() overload which takes IComparer object as parameter:

var outputDate = myEvents.OrderByDescending(x=>x.StartDate,new StringDateComparer());
Ehsan Sajjad
  • 61,834
  • 16
  • 105
  • 160
  • Thank you very much. I didnot try this but it helped me to understand how I can use Comparer in Order linq statements – Ziggler Sep 15 '15 at 19:03