如何为list创建新的通用项
本文关键字:创建 list | 更新日期: 2023-09-27 17:53:59
给定一个可能有5个项目的列表,下面的方法将返回一个恰好有5个项目的新列表(如果原始列表少于5个,则添加更多的项目)。这工作得很好,但现在我需要重构它,以便它可以处理一个通用的T列表(具有相同属性的T)。我如何将此方法转换为接受列表并使其返回一个具有5个元素的新列表?
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;
}
谢谢你。
你不能轻易地将你的方法转换为处理泛型列表,因为你的方法不是泛型的。它要求列表中的每个项目都具有属性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;
}
已经说过这个方法看起来不是很通用,因为约束非常具体。为什么要使其通用?
对于任意T
,您有两个选择:
- 添加
where T : SomeType
约束,其中SomeType
是一个基类或(更可能和更通用)一个接口,声明您需要的属性 - 切换到使用
dynamic
(或4.0之前的反射)来访问属性
第一个提供了编译时安全性,但需要T
;第二种不要求通用性,但完全是运行时的——没有静态分析检查。
interface IRenameThis {
int Year {get;set;}
int Cnt {get;set;}
}
并将where T : IRenameThis
添加到方法签名中(在参数的结束)
和方法体的开始{
之间)
static List<T> CreateFiveYearTemplate( int startYear
,int endYear
,ObjectResult<T> result)
where T : FiveYearComplex, new()
{
...
}