1

I have inherited a custom class from List<T> But after sorting my variable becomes NULL

public class Test
    {
        public int No { get; set; }
    }

    public class TestList : List<Test>
    {

    }

    class Program
    {
        static void Main(string[] args)
        {
            TestList tests = new TestList() { 
                new Test(){ No = 101 },
                new Test(){ No = 201 },
                new Test(){ No = 300 },
                new Test(){ No = 401 },
                new Test(){ No = 500 },
                new Test(){ No = 601 }
            };
            tests = tests.OrderBy(o => o.No).ToList() as TestList;

        }

    }

Could anybody please let me know why would TestList become null and how do I order by on this List?

Tim Liberty
  • 2,099
  • 4
  • 23
  • 39
  • `ToList()` returns an instance of [`System.Collections.Generic.List`](https://msdn.microsoft.com/en-us/library/6sh2ey19(v=vs.110).aspx) that does not derive of your type `TestList`. A new instance is created in `ToList()`. Use [`Sort`](https://msdn.microsoft.com/en-us/library/w56d4y5z(v=vs.110).aspx) to sort your list without creating a new instance. – Sebastian Schumann Mar 29 '16 at 11:26

3 Answers3

3

tests.OrderBy(o => o.No).ToList() returns List<Test>. List<Test> cannot be casted to TestList - it should be obvious due to inheritance. When cast is impossible, operator as returns null (your case).

You can do the following:

public class TestList : List<Test>
{
   public TestList ()
   {
   }

   public TestList (IEnumerable<Test> items)
        : base(items)
   {
   }
}

tests = new TestList(tests.OrderBy(o => o.No));

But it is bette to use Sort (LINQ is not neccessary).

tests.Sort(delegate(Test x, Test y)
{
    return x.No.CompareTo(y.No);
});

or even simpler:

tests.Sort((Test x, Test y) => x.No.CompareTo(y.No));

Reference

pwas
  • 3,225
  • 18
  • 40
2

The result of .ToList() is a List<Test>. The statement x as TestList will only succeed if x is either a TestList or a subclass of TestList. Because both isn't the case, the statement returns null.

Note that in general it is not recommended(*) to inherit from List<> or from other generic classes. It is better to use them directly. Subclassing often does not make sense, isn't needed or does not add anything, and last but not least it causes these kinds of problems.

(*): see this question & answers: Why not inherit from List<T>?

Community
  • 1
  • 1
Peter B
  • 22,460
  • 5
  • 32
  • 69
1

You can solve this by adding a constructor to your TestList class:

public class TestList : List<Test>
{
    public TestList()
    {
    }

    public TestList(IOrderedEnumerable<Test> others)
    {
        foreach (var test in others)
            Add(test);
    }
}

Then in code, you can write:

    var tests = new TestList() {
        new Test(){ No = 101 },
        new Test(){ No = 201 },
        new Test(){ No = 300 },
        new Test(){ No = 401 },
        new Test(){ No = 500 },
        new Test(){ No = 601 }
    };
    var newList = new TestList(tests.OrderBy(o => o.No));

But I do agree with the previous answer - using Sort() is better.

Pedro G. Dias
  • 3,162
  • 1
  • 18
  • 30