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
                    }
            );
5
  • it not exact duplicate, OP scenario is different Commented Sep 15, 2015 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. Commented Sep 15, 2015 at 18:23
  • You've obviously seen what I believe is duplicate of you question since it first link to search for title of your post (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. Commented Sep 15, 2015 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... Commented Sep 15, 2015 at 18:29
  • @Ziggler stackoverflow.com/a/3309397/477420 shows perfect example of custom comparer... Commented Sep 15, 2015 at 18:32

2 Answers 2

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; }
}
Sign up to request clarification or add additional context in comments.

2 Comments

better yet would be to set the MyStartDate property when creating a MyEvent and making MyEvent immutable..
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
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());

1 Comment

Thank you very much. I didnot try this but it helped me to understand how I can use Comparer in Order linq statements

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.