Writing a function to filter a list of elements by a property on it of a base type in C #

Let's say we have some types defined like this:

public class BaseClass { public int Value { get; set; } } public class SubClassA : BaseClass { public bool SomeBoolValue { get; set; } } public class SubClassB : BaseClass { public decimal SomeDecimalValue { get; set; } } 

And we will build two type subclass type lists

 List<SubClassA> subClassAList = new List<SubClassA> { new SubClassA {SomeBoolValue = true, Value = 0}, new SubClassA {SomeBoolValue = true, Value = 2}, new SubClassA {SomeBoolValue = false, Value = 1}, }; List<SubClassB> subClassBList = new List<SubClassB> { new SubClassB {SomeDecimalValue = 1.3M, Value = 2}, new SubClassB {SomeDecimalValue = 3.5M, Value = 1}, new SubClassB {SomeDecimalValue = 0.2M, Value = 5}, }; 

Is there a way to implement a function that can filter both subClassAList and subClassBList in the Value property? I know that this can be achieved by casting the results of such a function:

  public static IEnumerable<BaseClass> OrderList(IEnumerable<BaseClass> list) { return list.OrderBy(x => x.Value); } ... ... orderedAList = OrderList(subClassAList) .Cast<SubClassA>() //Don't like requiring a cast. Unsafe. .ToList(); 

But then we need to pass the results in order to return them back to the list of the subclass, which does not look very typical. I know that the ordering operation itself is very simple and probably does not require a separate function to perform the action, but if you are trying to do something more complex than ordering, it would be useful to contain the logic for a single function / class / what, to achieve this, not copy the code.

+5
source share
3 answers

You can accomplish this using a generic method.

 public static IEnumerable<T> OrderList<T>(IEnumerable<T> list) where T : BaseClass { return list.OrderBy(x => x.Value); } 
+3
source

You should add an interface for these classes as follows:

  public interface IBaseClass { int Value { get; set; } } ublic class BaseClass:IBaseClass { public int Value { get; set; } } public class SubClassA : BaseClass,IBaseClass { public bool SomeBoolValue { get; set; } } public class SubClassB : BaseClass,IBaseClass { public decimal SomeDecimalValue { get; set; } } 

And now you can easily filter both subClassAList and subClassBList in the Value property.

 public static IEnumerable<IBaseClass> OrderList(IEnumerable<IBaseClass> list) { return list.OrderBy(x => x.Value); } orderedAList = OrderList(subClassAList) .ToList() 
0
source

You can use a generic class to solve this problem, as shown below:

 class LinqUtil<T> where T : BaseClass { static void MyMain() { List<SubClassA> subClassAList = new List<SubClassA> { new SubClassA {SomeBoolValue = true, Value = 0}, new SubClassA {SomeBoolValue = true, Value = 2}, new SubClassA {SomeBoolValue = false, Value = 1}, }; List<SubClassB> subClassBList = new List<SubClassB> { new SubClassB {SomeDecimalValue = 1.3M, Value = 2}, new SubClassB {SomeDecimalValue = 3.5M, Value = 1}, new SubClassB {SomeDecimalValue = 0.2M, Value = 5}, }; IList<SubClassA> orderedAList = LinqUtil<SubClassA>.OrderList(subClassAList) .ToList(); IList<SubClassB> orderedBList = LinqUtil<SubClassB>.OrderList(subClassBList) .ToList(); } public static IEnumerable<T> OrderList(IEnumerable<T> list) { return list.OrderBy(x => x.Value); } } 
0
source

Source: https://habr.com/ru/post/1258380/


All Articles