tags:

views:

96

answers:

7

Hi Yes, I'm new to c#! :) i'm using .Net4 VS2010.

I have Three classes each one is used to build a list of objects of that type. All three inherit form a base class.

I want to combine the resulting three lists in to one and sort them on one of the base class elements.

Can this be done with lists of different types?

Simplified Example:

Each list is created

public List<TestOne> TestOne list;
public List<TestTwo> TestTwoList;
public List<object> BothLists;

Code to fill TestOne and TestTwo…

What/How do I combine both TestOne and TestTwo into BothLists and sort them on SeqNumber???

public class BaseClassTest 
{
    public string Loc { get; set; }  // loc
    // sequence number to order by will be assigned in the resulting class
    public int SeqNumber { get; set; } 
}

public class TestOne : BaseClassTest
{
    public int Number { get; set; } 
} 

public class TestTwo : BaseClassTest
{
    public string CatName { get; set; } 
} 
+2  A: 

"BothLists" should be a List<BaseClassTest>. That should let you sort on base class properties, using .OrderBy(x => x.SequenceNumber).

EDITED TO ADD:

Following up from comments, this should work to combine the lists:

BothLists = TestOneList.OfType<BaseClassList>().Concat().(TestTwoList.OfType<BaseClassList>()).ToList();

Generally, .OfType<>() is preferable to .Cast<>() because it simply filters based on type, rather than forcing a cast.

Cylon Cat
And to combine them first you would...
Marc
Depending on how big the list is they may want to sort in place.
ChaosPandion
+1  A: 

Given your example this is quite easy:

public List<BaseClassTest> BothLists;

Then you can sort:

BothLists.Sort((a, b) => a.SeqNumber.CompareTo(b.SeqNumber));  
ChaosPandion
+1  A: 

If a class inherits from a base, it counts as the base class for most operations. Thus:

List<BaseClassTest> AllTests;

Should get you what you need.

AllenG
+5  A: 

You should be able to do:

List<BaseClassTest> sorted = TestOneList.Cast<BaseClassTest>()
                    .Union(TestTwoList.Cast<BaseClassTest>())
                    .OrderBy(item => item.SeqNumber)
                    .ToList();

This will do your sort + union all at once.

Reed Copsey
+1 most complete. `Union` removes duplicates (vs `AddRange`) and I have a feeling that's what the OP wants, but wanted to mention for googlers.
Marc
This is the best example that uses a declarative style. I can't say I like the building of the list then ordering then building a second list in some other answers.
ChaosPandion
nice. typo: var sorted = listOne.Cast<BaseClassTest>() .Union(listTwo.Cast<BaseClassTest>()) .OrderBy(item => item.SeqNumber).ToList();
Mike Stockdale
Thank you all for these answersThis was the first one I tried and it works :)
Adrian
BaseClassText should be BaseClassTest
Mike Stockdale
@Mike: Thanks - fixed :)
Reed Copsey
How do I make the "sorted" a public variable to I can access it from different functions?
Adrian
@Adrian: You'll just need to have it as a class variable, and assign it when you sort.
Reed Copsey
Thanks the problem is/was that I could not use Var as the type as a class Variable. Is this correct?I got around it by typing it as the baseclassTest, what I'm not understanding is casting it as the baseClassTest how can it still contain the additional fields??
Adrian
@Adrian: Yes - you can't use var in a class level variable.
Reed Copsey
@Adrian: The objects don't change when you cast - you can just treat them as a base class. For details, see: http://en.wikipedia.org/wiki/Liskov_substitution_principle
Reed Copsey
@Reed thanks again.
Adrian
A: 

Make TestOne and TestTwo implement the IComparable interface. See here. Then you can combine the lists into an ArrayList and use the Sort method.

YWE
A: 
List<BaseClassTest> list3 = new List<BaseClassTest>();
list3.AddRange(list1);
list3.AddRange(list2);
var sorted = list3.OrderBy(e => e.SequenceNum).ToList(); //if you really need a list back

This is all assuming you have Linq available. Of course if you do a Union statement might work also.

Casey
doesn't compile
Mike Stockdale
A: 
  var both = new List<BaseClassTest>();
  foreach (var one in listOne) both.Add(one);
  foreach (var two in listTwo) both.Add(two);
  var sort = both.OrderBy(s => s.SeqNumber);
Mike Stockdale