给出可能的5个项目的列表,下面的方法将返回一个恰好5个项目的新列表(如果原始列表少于5个,则添加更多项目)。这工作正常,但现在我需要重构它,以便它可以处理一个通用的T列表(一个具有相同的年和Cnt属性)。如何将此方法转换为List并让它返回一个包含5个元素的新List?
private static List<FiveYearComplex> CreateFiveYearTemplate(int startYear,
int endYear, ObjectResult<FiveYearComplex> result)
{
var list = new List<FiveYearComplex>(5);
for (int year = startYear; year < endYear; ++year)
{
list.Add(new FiveYearComplex() { Year = year, Cnt = 0 });
}
FiveYearComplex tmpItem;
foreach (var item in result)
{
tmpItem = list.Find(w => w.Year == item.Year);
if (tmpItem == null)
{
tmpItem = new FiveYearComplex() { Cnt = 0, Year = item.Year };
}
else
{
tmpItem.Cnt = item.Cnt;
}
}
return list;
}
当我尝试使用List时,我最终会遇到这一部分:
for (int year = startYear; year < endYear; ++year)
{
list.Add(new T() { Year = year, Cnt = 0 });
}
我收到错误......
谢谢!
为了完整性:
public interface IYearTemplate
{
int? Year { get; set; }
decimal? Cnt { get; set; }
}
private static List<T> CreateFiveYearTemplate <T> (
int startYear, int endYear,
ObjectResult<FiveYearAttendanceComplex> result)
where T : IYearTemplate, new()
{
var list = new List<T>(5);
for (int year = startYear; year < endYear; ++year)
{
list.Add(new T() { Year = year, Cnt = 0 });
}
T tmpItem;
foreach (var item in result)
{
tmpItem = list.Find(w => w.Year == item.Year);
if (tmpItem == null)
{
tmpItem = new T() { Cnt = 0, Year = item.Year };
}
else
{
tmpItem.Cnt = item.Cnt;
}
}
return list;
}
谢谢你。
答案 0 :(得分:4)
您无法轻松转换您的方法来处理通用列表,因为您的方法不是通用的。它要求列表中的每个项目都具有属性Cnt
和Year
,因为您的方法是通用的,您必须添加此约束。
public interface IYearTemplate
{
int Cnt {get;set;}
int Year {get;set;}
}
此外,您的方法需要一个默认构造函数,它表示为约束new()
- 所以它看起来像这样:
private static List<T> CreateFiveYearTemplate<T>(int startYear,
int endYear, ObjectResult<T> result) where T: IYearTemplate, new()
{
var list = new List<T>(5);
for (int year = startYear; year < endYear; ++year)
{
list.Add(new T() { Year = year, Cnt = 0 });
}
T tmpItem;
foreach (var item in result)
{
tmpItem = list.Find(w => w.Year == item.Year);
if (tmpItem == null)
{
tmpItem = new T() { Cnt = 0, Year = item.Year };
}
else
{
tmpItem.Cnt = item.Cnt;
}
}
return list;
}
说过这个方法看起来不太通用,因为约束是非常具体的。为什么希望使其成为通用的?
答案 1 :(得分:3)
为了适用于任意T
,您有两种选择:
where T : SomeType
约束,其中SomeType
是基类或(更可能更通用)的接口,用于声明所需的属性dynamic
(或4.0之前的反射)来访问属性第一个给你编译时安全性,但需要T
之间的一些共性;第二个要求没有共性,但完全是运行时 - 没有静态分析检查。
例如:
interface IRenameThis {
int Year {get;set;}
int Cnt {get;set;}
}
将where T : IRenameThis
添加到方法签名中(在关闭参数)
之间和方法正文的开放{
之间)
答案 2 :(得分:1)
static List<T> CreateFiveYearTemplate( int startYear
,int endYear
,ObjectResult<T> result)
where T : FiveYearComplex, new()
{
...
}