2009-05-10 36 views
34

Thông thường, tôi muốn chọn List<String> [hay, trong VB, List(Of String)] trên StringCollection bất cứ khi nào có thể: xem thêm Best string container.Chuyển đổi StringCollection vào danh sách <String>

Tuy nhiên, có vẻ như, generics - và do đó, List<String> - dường như không được hỗ trợ trong thiết kế cài đặt của VS 2008. Do đó, nếu tôi muốn sử dụng danh sách các chuỗi trong cài đặt người dùng của mình, tôi phải sử dụng số StringCollection tại đó.

Bây giờ, vì tôi không muốn thấy StringCollection trong suốt mã của mình, tôi cần phải chuyển đổi nó thành List<String>. Làm thế nào để tôi làm điều này một cách hiệu quả? Hoặc, thậm chí tốt hơn, tôi có nhầm lẫn và có cách nào để sử dụng List<String> trong trình thiết kế cài đặt không?

CHỈNH SỬA: Tôi phải sử dụng .NET 2.0.

Trả lời

13

Nếu bạn sử dụng .NET 2.0, tôi sẽ tưởng tượng tùy chọn cleanliest sẽ là để tạo ra một wrapper cho StringCollection mà thực hiện IEnumerable<string>IEnumerator<string> cho StringCollectionStringEnumerator tương ứng. (lưu ý: theo siêu dữ liệu, StringEnumerator không triển khai IEnumerator). Mẫu dưới đây. Tuy nhiên, vào cuối ngày, một ai đó, một nơi nào đó sẽ thực hiện một số foreach() trên StringCollection, vì vậy một có thể cho rằng một đơn giản foreach(string item in stringCollection) và thêm vào List<string> sẽ đủ; Tôi nghi ngờ điều này sẽ không được thực hiện đủ cho nhu cầu của bạn.

Bạn cũng có thể thực hiện IList<string> sử dụng phương pháp này là tốt, để giúp bạn tiết kiệm nhân đôi chuỗi cơ bản, nhưng bạn sẽ phải trả tiền phạt của việc có các "wrapper" cuộc gọi loại đại biểu (một phương pháp gọi thêm về chồng!). Tôi sẽ đề nghị bạn xử lý mọi thứ trong giao diện trong hệ thống của bạn, dù sao, IEnumberable<string>, IList<string> vv, thay vì Danh sách cụ thể, nó sẽ hướng dẫn bạn xuống một con đường để linh hoạt hơn.

static void Main(string[] args) 
    { 
     StringCollection stringCollection = new StringCollection(); 
     stringCollection.AddRange(new string[] { "hello", "world" }); 

     // Wrap! 
     List<string> listOfStrings = new List<string>(new StringCollectionEnumerable(stringCollection)); 

     Debug.Assert(listOfStrings.Count == stringCollection.Count); 
     Debug.Assert(listOfStrings[0] == stringCollection[0]); 

    } 

    private class StringCollectionEnumerable : IEnumerable<string> 
    { 
     private StringCollection underlyingCollection; 

     public StringCollectionEnumerable(StringCollection underlyingCollection) 
     { 
      this.underlyingCollection = underlyingCollection; 
     } 

     public IEnumerator<string> GetEnumerator() 
     { 
      return new StringEnumeratorWrapper(underlyingCollection.GetEnumerator()); 
     } 

     System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
     { 
      return this.GetEnumerator(); 
     } 
    } 

    private class StringEnumeratorWrapper : IEnumerator<string> 
    { 
     private StringEnumerator underlyingEnumerator; 

     public StringEnumeratorWrapper(StringEnumerator underlyingEnumerator) 
     { 
      this.underlyingEnumerator = underlyingEnumerator; 
     } 

     public string Current 
     { 
      get 
      { 
       return this.underlyingEnumerator.Current; 
      } 
     } 

     public void Dispose() 
     { 
      // No-op 
     } 

     object System.Collections.IEnumerator.Current 
     { 
      get 
      { 
       return this.underlyingEnumerator.Current; 
      } 
     } 

     public bool MoveNext() 
     { 
      return this.underlyingEnumerator.MoveNext(); 
     } 

     public void Reset() 
     { 
      this.underlyingEnumerator.Reset(); 
     } 
    } 
84

Chuyển đổi StringCollection thành List<string> thật tuyệt vời nếu bạn đang sử dụng .NET 3.5.

var list = stringCollection.Cast<string>().ToList(); 

Về câu hỏi thứ hai của bạn, tôi dường như nhớ lại rằng bạn có thể sử dụng List<string> trong trình thiết kế cài đặt của Visual Studio. Nếu bạn chọn loại tùy chỉnh thì trình duyệt theo loại thích hợp, nó sẽ hoạt động. Tuy nhiên, tôi có thể bị nhầm lẫn về điều đó, vì vậy tôi sẽ cần phải xác minh nó.

+2

Nếu hiệu suất là một mối quan tâm, tôi muốn chọn Cast thay vì OfType, chỉ để tránh sự kiểm tra kiểu đó OfType đang thực hiện. Chúng tôi biết tất cả các trường hợp đều thuộc loại chuỗi. Dù sao, điều này có thể không đáng kể. –

+0

@Jerome: Vâng, bạn có thể đúng về điều đó, mặc dù thực sự nó sẽ không đáng kể trong hầu hết các tình huống. Việc gọi OfType thay vì Cast chỉ thực sự cần thiết khi bạn đang xử lý các bộ sưu tập kiểu hỗn hợp. (Không chắc chắn nếu bạn nhận ra tôi chỉ cần cập nhật câu trả lời ngay trước khi bình luận của bạn anyway, vì lý do chính xác này.) – Noldorin

+0

Không, bạn không thể nhập Danh sách trong Cài đặt: Tôi vừa thử nó. "Tùy chỉnh" không có sẵn trong VS2008/.Net2 và "Duyệt" không nhận ra nó. (có, tôi đang mắc kẹt với .NET2 trong thời gian này - 4.0 là trên thẻ nhưng không cho đến năm sau) – winwaed

2

Nếu bạn đang sử dụng C# 3.0 và .NET 3.5, bạn có thể tạo một danh sách sử dụng

var list = new List<string>(new StringCollection().Cast<string>()); 

Một cách khác xung quanh là:

var c = new StringCollection(); 
c.AddRange(new List<string>().ToArray()); 
5

Tại sao không giữ nó đơn giản và chỉ cần lặp mặc dù nó và thêm các mục vào danh sách, hoặc có tôi hiểu lầm một cái gì đó?

public static List<string> Convert(StringCollection collection) 
{ 
    List<string> list = new List<string>(); 
    foreach (string item in collection) 
    { 
     list.Add(item); 
    } 
    return list; 
} 
13

stringCollection.Cast<string>().ToList()

2

C# 2,0

StringCollection colString = new StringCollection(); 
string[] arrString = new string[colString.Count]; 
colString.CopyTo(arrString, 0); 
List<string> lstString = new List<string>(arrString); 
Các vấn đề liên quan