开发者

How to make a generic list equal another generic list

开发者 https://www.devze.com 2022-12-18 18:10 出处:网络
This is my set up, class CostPeriodDto : IPeriodCalculation { public decimal? a { get; set; } public decimal? b { get; set; }

This is my set up,

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
        {
            ret开发者_运维百科urn this.costPeriodList;  // compile error   
        }
    }
}

What would be the best way of doing this?


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 were using something implementing IEnumerable<out T>, you could simply do it the way you wrote it, and it would 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    
        } 
    } 
} 


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


The LINQ methods to cast from one sequence to another will not be equal. That is to say that the following test would fail if you used Cast()/ToList().

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

Furthermore, using those methods means that if you tried to add an item to one collection, they would not be reflected in the other. And every time you called periodCalcList, it would be creating an entirely new collection which could be disastrous depending on how many items, how frequently it's called, etc.

A better solution, in my opinion, is to not use List<T> for holding the CostPeriodDto and instead use a collection derived from Collection<T> and explicitly implement IEnumerable<IPeriodCalculation>. Optionally you could implement IList<IPeriodCalculation> if you needed 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; }
    }
}
0

精彩评论

暂无评论...
验证码 换一张
取 消