如何为 List创建新的通用项?
给定一个可能包含 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;
}
谢谢。
Given a list of a possible 5 items, the method below will return a new list of exactly 5 items (adding more items if the original list has less than 5). This works fine, but now I need to refactor it so that it can handle a generic T list (one that will have the same properties of year and Cnt). How can I convert this method to take in a List and have it return a new List with 5 elements?
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;
}
When I try to use List I eventually run into this section:
for (int year = startYear; year < endYear; ++year)
{
list.Add(new T() { Year = year, Cnt = 0 });
}
and I get an error...
Thanks!
For completeness:
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;
}
Thanks you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
为了使其适用于任意
T
,您有两种选择:where T : SomeType
约束,其中SomeType
是基类或者(更有可能且更通用)声明您需要切换到的属性的接口动态
(或4.0之前的反射)来访问属性第一个为您提供编译时安全性,但需要一些通用性在
T
之间;第二个不需要通用性,但完全是运行时的——没有静态分析检查。例如:
并将
where T : IRenameThis
添加到方法签名中(在参数的结束)
和方法主体的开始{
之间)For that to work for arbitrary
T
, you had two choices:where T : SomeType
constraint, whereSomeType
is either a base-class or (more likely and more versatile) an interface that declares the properties you needdynamic
(or reflection before 4.0) to access the propertiesThe first gives you compile-time safety, but requires some commonality between the
T
; the second demands no commonality, but is entirely runtime - no static-analysis checking.For example:
And add
where T : IRenameThis
to the method signature (between te closing)
of the parameters and te opening{
of the method body)您无法轻松地将您的方法转换为处理通用列表,因为您的方法不是通用的。它要求列表中的每个项目都具有属性
Cnt
和Year
,为了使您的方法具有通用性,您必须添加此约束。另外,您的方法需要一个默认构造函数,它表示为约束
new()
- 所以它可能看起来像这样:话虽如此,这个方法看起来不太通用,因为约束是 非常具体。为什么您想要使其通用?
You cannot easily convert your method to handle a generic list, because well your method is not generic. It requires for each item in the list to have properties
Cnt
andYear
, for your method to be generic you have to add this constraint.Also your method requires a default constructor, which is expressed as the constraint
new()
- so it could look like this:Having said that this method doesn't look very generic, since the constraints are very specific. Why do you want to make it generic?