2011-05-27 108 views
0

我很好奇,如果因为我受够了,我可以提高标准的通用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现有元素)也可以实现。

这怎么能改进?

+1

为什么你要写很多这样的代码呢? – jason 2011-05-27 13:26:40

+0

这个问题是基于好奇心 - 似乎相当无害,没有意识到我会从过去是一个支持性社区得到如此荒谬的回应。 – 2011-05-27 13:30:26

+1

你说过“我厌倦了写代码,比如......”,这似乎不仅仅是一种好奇心。此外,将回应描述为“荒谬”似乎并不积极参与所谓“支持性社群”的成员。 – jason 2011-05-27 21:55:07

回答

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(); 
0

你不应该这样做。你违反了“分离关注”原则。
为什么不只是声明一个从stringPerson的隐式转换,对于具有一个构造函数参数的情况?

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"); 

为了能够缩短代码添加具有多个构造函数参数的对象,我想你应该做到以下几点:
使用你直接创建在调用AddFunc

Func<string, string, Person> ctor = 
    (firstName, name) => new Person { Name = name, FirstName = firstName }; 
list.Add(ctor("Terry", "McDouglas")); 
list.Add(ctor("Jones", "Miller")); 

这是很多更清洁。

+0

我确信我明确暗示要通过多个参数来构造对象。 – 2011-05-27 13:13:52

+0

它仍然是无稽之谈。你在这里混合责任。 – 2011-05-27 13:14:58

+0

完全没有 - 消费代码保留了初始化发生的控制。 – 2011-05-27 13:16:22