How to make a generic list equal to another generic list

This is my setting

class CostPeriodDto : IPeriodCalculation { public decimal? a { get; set; } public decimal? b { get; set; } public decimal? c { get; set; } public decimal? d { get; set; } } interface IPeriodCalculation { decimal? a { get; set; } decimal? b { get; set; } } class myDto { public List<CostPeriodDto> costPeriodList{ get; set; } public List<IPeriodCalculation> periodCalcList { get { return this.costPeriodList; // compile error } } } 

What would be the best way to do this?

+6
c #
source share
3 answers

Use Cast<IPeriodCalculation>() :

 public class CostPeriodDto : IPeriodCalculation { public decimal? a { get; set; } public decimal? b { get; set; } public decimal? c { get; set; } public decimal? d { get; set; } } public interface IPeriodCalculation { decimal? a { get; set; } decimal? b { get; set; } } public class myDto { public List<CostPeriodDto> costPeriodList { get; set; } public List<IPeriodCalculation> periodCalcList { get { return this.costPeriodList.Cast<IPeriodCalculation>().ToList(); } } } 

I believe in C # 4, if you used something that implements IEnumerable<out T> , you could just do it the way you wrote it and it will be resolved using covariance .

 class myDto { public IEnumerable<CostPeriodDto> costPeriodList{ get; set; } public IEnumerable<IPeriodCalculation> periodCalcList { get { return this.costPeriodList; // wont give a compilation error } } } 
+9
source share

Try return this.costPeriodList.Cast<IPeriodCalculation>().ToList() .

+3
source share

LINQ methods for translating from one sequence to another will not be equal. That is, the next test will fail if you used Cast()/ToList() .

 Assert.AreSame(myDto.costPeriodList, myDto.periodCalcList); 

In addition, using these methods means that if you try to add an item to one collection, they will not be reflected in another. And every time you called periodCalcList, it would create a completely new collection, which could be catastrophic depending on how many elements, how often this is called, etc.

The best solution, in my opinion, is not to use List<T> to store CostPeriodDto and instead use the collection obtained from Collection<T> and explicitly implement IEnumerable<IPeriodCalculation> . If you wish, you could implement IList<IPeriodCalculation> if you need to.

 class CostPeriodDtoCollection : Collection<CostPeriodDto>, IEnumerable<IPeriodCalculation> { IEnumerable<IPeriodCalculation>.GetEnumerator() { foreach (IPeriodCalculation item in this) { yield return item; } } } class MyDto { public CostPeriodDtoCollection CostPeriods { get; set; } public IEnumerable<IPeriodCalculation> PeriodCalcList { get { return CostPeriods; } } } 
+1
source share

All Articles