2011-05-27 58 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