0

first of all congrats for the web, this is my first question but I have found a lot of answer before here. Here my problem: I have to take some data from an excel file and print them off in a file. Until here everything is ok. But depending on the order of the file list, I take the data in one or another order. My proposal is after all the data have been taken from the excel, to sort those data by the date of the bill (one of the elements of the data). I am describing my classes below.

I have my Bill class:

class Bill
{
    private string billNumber;
    private string billDate;
    private DateTime date;
    private string from;
    private string to;
    private string billCost;
    private string power1;
    private string power2;
    private string power3;
    private string power4;
    private string power5;
    private string power6;
    private string contractNumber;
}

And this is my Contract Class:

class Contract
{
    private List<Bill> billList;
    private Dictionary<double, Bill> billsDictionary;
    private double contractNumber;
}

After in my program I have a List<Contract>. I would like to sort the List<Bill> of the Contract class by the date, to be able to print the bill in the correct order, but I have not been able to find any solution to order them.

Thanks in advance.

Greetings.

user2864740
  • 60,010
  • 15
  • 145
  • 220
ars1614
  • 69
  • 1
  • 11
  • You can use LINQ methods to order the list easyly with `OrderBy`, `OrderByDescending` and `ThenBy` methods. Have a look at [**this**](http://stackoverflow.com/questions/12080322/sort-list-of-class-elements) question. – Farhad Jabiyev Jul 29 '14 at 06:34
  • possible duplicate of [Sort a Custom Class List<>](http://stackoverflow.com/questions/3163922/sort-a-custom-class-list) – user2864740 Jul 29 '14 at 06:36
  • Also, http://stackoverflow.com/questions/3309188/how-to-sort-a-listt-by-a-property-in-the-object?rq=1 – user2864740 Jul 29 '14 at 06:37
  • Looks strange, why your Bill is full of private fields. Incapsulate them with public fields with only getters and then use LINQ like in top comment – Alex Voskresenskiy Jul 29 '14 at 06:38
  • 1
    [**Never** use a floating point number as the key for a dictionary!!!](http://stackoverflow.com/questions/4915462/how-should-i-do-floating-point-comparison) – Bas Jul 29 '14 at 06:41
  • @AlexVoskresenskiy Because I have more public properties but I did not put here because of the space. And I have had a look at those question of course, but I could not solve the problem. The list did not get ordered. – ars1614 Jul 29 '14 at 06:43
  • @BasBrekelmans At the beginning I used an int to that field, but the contract number was too long and the int class could not afford the dimension, that was the reason why I had to use the double. Any better solution? – ars1614 Jul 29 '14 at 06:49
  • You can use a long, that has 64 bit capacity instead of 32 bit, otherwise use a string – Bas Jul 29 '14 at 06:51
  • @BasBrekelmans Of course "long"!! I totally forgot that type. Ta! – ars1614 Jul 29 '14 at 06:56

2 Answers2

0

You should be able to do that using linq like q = q.OrderBy(a => a.ColumnName) but you may want to check the access modifiers of your properties, being private you won't be able to access them from the outside.

Here's a simple example on ordering with Linq:

        class Pet
        {
            public string Name { get; set; }
            public int Age { get; set; }
        }

        public static void OrderByEx1()
        {
            Pet[] pets = { new Pet { Name="Barley", Age=8 },
                           new Pet { Name="Boots", Age=4 },
                           new Pet { Name="Whiskers", Age=1 } };

            IEnumerable<Pet> query = pets.OrderBy(pet => pet.Age);

            foreach (Pet pet in query)
            {
                Console.WriteLine("{0} - {1}", pet.Name, pet.Age);
            }
        }

        /*
         This code produces the following output:

         Whiskers - 1
         Boots - 4
         Barley - 8
        */

Notice how the properties of the class are public so you can access them from anywhere in the code.

More info on sorting can be found here.

Nahuel Ianni
  • 3,177
  • 4
  • 23
  • 30
0

There are two solutions. First you need to expose property that can be used to sort.

public class Bill
{
    // ... rest of your code 

    public DateTime Date  
    {   
        get 
        {
            return this.date;
        }
    }
}

1) You can use List's Sort with passed comparer (msdn):

public class Comp : IComparer<Bill>
{
    public int Compare(Bill x, Bill y)
    {
       // remember to handle null values first (x or y or both are nulls)
       return x.Date.CompareTo(y.Date);
    }
}

then:

billList.Sort(new Comp());

Keep in mind: if you declare Comp as nested class of Bill you won't have to add property Date. You will be able to see private fields of Bill and use it for comparsion..

2) You can use linq (it creates new instance of List):

billList = billList.OrderBy(bill => bill.Date).ToList();
  • Thanks It worked! I saw that method before but it did not work because I had a problem with the class. I had coded the Date property bad and it was giving wrong values. Thank you very very much. – ars1614 Jul 29 '14 at 07:14
  • @ars1614 I'm glad :) Feel free to accept the answer if helped :) –  Jul 29 '14 at 07:22