I have created two lists say X & Y. These two lists are of different types.
(ie List<class_A> X
& List<class_B> Y
).
Values in both these lists are different. But there is a DateTime
field in both these lists.
I need to sort these lists according to the date
field.
I have separate functions to print the details of list A and List B.
Suppose the sorted list looks like
My purpose is to loop through this list and call the appropriate function to display the details. ie if the tuple is from list A then call the function for printing list A's details and vice versa.
You can create an interface
to host your common properties and functions, then join those lists after casting to this interface and sort it then:
interface ICommon
{
DateTime DT { get; }
void Print();
}
class ClassA : ICommon
{
public DateTime DT { get; set; }
public void Print() { Console.WriteLine("A " + DT); }
}
class ClassB : ICommon
{
public DateTime DT { get; set; }
public void Print() { Console.WriteLine("B " + DT); }
}
public static void Main()
{
var listA = new List<ClassA> { new ClassA() { DT = DateTime.Now.AddDays(-1) }, new ClassA() { DT = DateTime.Now.AddDays(-3) }};
var listB = new List<ClassB> { new ClassB() { DT = DateTime.Now.AddDays(-2) }, new ClassB() { DT = DateTime.Now.AddDays(-4) }};
var orderedResult = listA.Cast<ICommon>()
.Concat(listB.Cast<ICommon>())
.OrderBy(q => q.DT);
//or possibly even better:
//var orderedResult = listA.Concat<ICommon>(listB).OrderBy(q => q.DT);
foreach (var obj in orderedResult)
obj.Print();
}
If you can change the definition of class A
and class B
then you should use one of the other answers here which tells you to add an interface to both those classes.
However, if you cannot change the definition of class A
and class B
(perhaps because they are defined in a library that you can't change) then you must take a different approach.
One solution which keeps things fairly neat is to introduce a wrapper class which holds either an instance of class A
or class B
(but not both).
Assume that that your classes look like this:
class A
{
public DateTime Date;
public double Value;
public void Print() {}
}
class B
{
public DateTime Date;
public string Value;
public void Print() { }
}
You can write a simple wrapper that looks like this:
class Wrapper
{
readonly A a;
readonly B b;
public Wrapper(A a)
{
this.a = a;
}
public Wrapper(B b)
{
this.b = b;
}
public DateTime Date => a?.Date ?? b.Date;
public void Print()
{
if (a != null)
a.Print();
else
b.Print();
}
}
Then given two lists:
var listA = new List<A>();
var listB = new List<B>();
You can create a sorted list of Wrapper
objects:
var sorted =
listA.Select(a => new Wrapper(a))
.Concat(listB.Select(b => new Wrapper(b)))
.OrderBy(item => item.Date);
Then to call the appropriate Print()
method for each item in the sorted list:
foreach (var item in sorted)
item.Print();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With