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

时间:2010-02-03 04:30:26

标签: c#

这是我的设置,

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 个答案:

答案 0 :(得分: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>的内容,您可以按照编写它的方式进行操作,并使用Covariance进行解决。

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

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

答案 1 :(得分:3)

尝试return this.costPeriodList.Cast<IPeriodCalculation>().ToList()

答案 2 :(得分:1)

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

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

此外,使用这些方法意味着如果您尝试将项目添加到一个集合,则它们不会反映在另一个集合中。每次调用periodCalcList时,都会创建一个全新的集合,这可能是灾难性的,具体取决于项目的数量,调用频率等等。

在我看来,更好的解决方案是不使用List<T>来保存CostPeriodDto,而是使用从Collection<T>派生的集合并明确实现IEnumerable<IPeriodCalculation>。如果需要,您可以选择实施IList<IPeriodCalculation>

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; }
    }
}