我很好奇我是否可以增强标准的通用List<>
功能,因为我厌倦了编写代码,如:
var list = new List<Person>{
new Person{Name = "David", Age = 24},
new Person{Name = "John", Age = 30}
};
list.Add(new Person{Name = "Terry", Age = 28});
我希望隐式构建T
。我想出的最好的东西允许我用最多四个对象构造参数来做这个:
var list = new ListWithConstructor<string, int, Person>(
(name,age) => new Person { Name = name, Age = age })
{
{"David", 24},
{"John", 30}
};
list.Add("Terry", 28);
这是这样实现的:
public class ListWithConstructor<T1, T> : List<T>
{
private readonly Func<T1, T> itemConstructor;
public ListWithConstructor(Func<T1, T> itemConstructor)
{
this.itemConstructor = itemConstructor;
}
public void Add(T1 arg1)
{
base.Add(itemConstructor(arg1));
}
}
public class ListWithConstructor<T1, T2, T> : List<T>
{
private readonly Func<T1, T2, T> itemConstructor;
public ListWithConstructor(Func<T1, T2, T> itemConstructor)
{
this.itemConstructor = itemConstructor;
}
public void Add(T1 arg1, T2 arg2)
{
base.Add(itemConstructor(arg1, arg2));
}
}
......等等最多四个参数。
显然,其他List<>
构造函数(获取容量和IEnumerable
现有元素)也可以实现。
如何改进?
答案 0 :(得分:1)
您正在寻找的功能(几乎)已经触手可及:
var names = new[] { "David", "John" };
var persons = new List<Person>(names.Select(name => new Person { Name = name }));
通过这种方式,您也可以清楚地分离关注点; List
完全不参与对象构造(甚至不是仅通过调用委托),而是简单地分配了一系列对象。转换是分开处理的。
这也可以处理将多个值转换为单个对象的情况:
public static IList<Person> GetListFromNamesAndAges(string[] names, int[] ages)
{
if (names.Length != ages.Length)
{
throw new ArgumentException("names and ages must be of equal length.");
}
return new List<Person>(
names.Select((name, index) =>
new Person { Name = name, Age = ages[index] }));
}
// usage example:
var persons = GetListFromNamesAndAges(
new[] {"David", "John"},
new[] {24, 30});
如果将两个列表中的值合并为单个对象,则使用Zip
可能会提供稍微清晰的代码;
return names
.Zip(ages, (name, age) => new Person {Name = name, Age = age})
.ToList();
答案 1 :(得分:0)
你不应该这样做。您违反了“关注分离”原则
为什么不为具有一个构造函数参数的情况声明从string
到Person
的隐式转换?
public class Person
{
public Person(string name)
{
Name = name;
}
public string Name { get; set; }
public static implicit operator Person(string name)
{
return new Person(name);
}
}
var list = new List<Person>();
list.Add("Terry");
为了能够缩短添加具有多个构造函数参数的对象的代码,我认为您应该执行以下操作:
在Func
:
Add
Func<string, string, Person> ctor =
(firstName, name) => new Person { Name = name, FirstName = firstName };
list.Add(ctor("Terry", "McDouglas"));
list.Add(ctor("Jones", "Miller"));
很多更清洁。