2010-02-03 43 views
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

嘗試return this.costPeriodList.Cast<IPeriodCalculation>().ToList()

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

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