如何使一个通用列表等于另一个通用列表

6
这是我的设置,
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   
        }
    }
}

什么是最好的做法?
3个回答

9

使用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();         
        }
    }
}

我相信在C#4中,如果你使用实现了IEnumerable<out T>的东西,你可以简单地按照你写的方式去做,它将会被解决使用协变性

class myDto 
{ 
    public IEnumerable<CostPeriodDto> costPeriodList{ get; set; } 

    public IEnumerable<IPeriodCalculation> periodCalcList 
    { 
        get 
        { 
            return this.costPeriodList;  // wont give a compilation error    
        } 
    } 
} 

3
尝试使用以下代码:return this.costPeriodList.Cast<IPeriodCalculation>().ToList()

1

从一个序列转换到另一个序列的LINQ方法将不会是“相等的”。也就是说,如果您使用Cast()/ToList(),以下测试将失败。

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

此外,使用这些方法意味着,如果您尝试向一个集合添加一个项目,它们不会反映在另一个集合中。每次调用periodCalcList时,它将创建一个全新的集合,这可能取决于有多少项、调用频率等,这可能是灾难性的。
我认为更好的解决方案是,不要使用List来保存CostPeriodDto,而是使用从Collection派生的集合,并显式实现IEnumerable。如果需要,还可以实现IList。
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; }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接