这是我的设置,
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
}
}
}
这样做的最佳方式是什么?
答案 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; }
}
}