2010-10-19 18 views
10

Khi tiêu đề cho biết: Tại sao string.Join cần lấy một mảng thay vì một IEnumerable? Điều này khiến tôi khó chịu, vì tôi phải thêm một .ToArray() khi tôi cần tạo một chuỗi kết nối từ kết quả của một biểu thức LINQ.Lý do string.Join cần phải lấy một mảng thay vì một IEnumerable?

Trải nghiệm của tôi cho tôi biết rằng tôi thiếu một số thứ hiển nhiên ở đây.

+2

Bạn sẽ rất vui khi biết rằng nó chấp nhận 'IEnumerable 'trong.NET 4 –

+0

Đoán của tôi là nó đã được thêm trước khi IEnumerable tồn tại. – asawyer

+0

string.Join đã ở đây rất lâu trước Linq. Làm thế nào nó làm phiền bạn? Chỉ còn vài ký tự nữa để viết. –

Trả lời

9

nâng cấp lên NET 4.0 và sử dụng overload chấp nhận IEnumerable<string>. Nếu không, chỉ chấp nhận rằng đó là một vấn đề tồn tại lâu dài mà không được giải quyết cho đến khi .NET 4.0. Bạn cũng có thể khắc phục vấn đề bằng cách tạo phương pháp mở rộng của riêng mình!

public static class StringEnumerableExtensions { 
    public static string Join(this IEnumerable<string> strings, string separator) { 
     return String.Join(separator, strings.ToArray()); 
    } 
} 

Cách sử dụng:

IEnumerable<string> strings; 
Console.WriteLine(strings.Join(", ")); 
+0

Jason, cảm ơn rất nhiều, lập trình đã trở nên rất vui vẻ! ':)' – sbi

+0

BTW, tôi thực sự đã viết một 'Tham gia (IEnumerable chuỗi, chuỗi tách)' trên đầu trang của điều đó. Tôi đã yêu rất nhiều điều đó, tôi đã trải qua 100kLoC và điều chỉnh mọi cách sử dụng 'string.Join()'. – sbi

3

Nó không còn nữa. .NET 4 đã thêm some overloads để dễ sử dụng hơn. Đặc biệt, không chỉ bạn không cần phải vượt qua trong một mảng - nó không cần phải là một chuỗi chuỗi. String.Join(String, IEnumerable<T>) sẽ gọi ToString trên mỗi mục trong chuỗi.

Nếu bạn không sử dụng .NET 4 nhưng đang thực hiện nhiều thao tác nối chuỗi, bạn luôn có thể viết các phương thức của riêng mình, tất nhiên.

+0

Bạn đang nói với tôi không có lý do .NET <4 làm điều này? – sbi

+0

@sbi: Yup. Nó chỉ là một cái gì đó mà MS có lẽ đã không nhận ra sẽ hữu ích cho các nhà phát triển. Nó không cần bất kỳ tính năng mới nào từ .NET 4, theo như tôi biết. –

+0

Và ở đây tôi đã mong đợi một điều trị lâu dài và giáo dục về những lý do tại sao phải là một mảng ... – sbi

8

Overloads of Join that take an IEnumerable<T> argument đã được giới thiệu trong .NET 4 - nếu bạn không sử dụng .NET 4 thì tôi sợ bạn bị kẹt với việc truyền mảng hoặc viết bản triển khai của riêng bạn.

Tôi đoán rằng lý do đơn giản là nó không được coi là đủ quan trọng khi khung được thiết kế lần đầu tiên. IEnumerable<T> trở nên nổi bật hơn nhiều với sự ra đời của LINQ.

(Tất nhiên, không có loại chung trong .NET khi nó được thiết kế, nhưng không có lý do tại sao họ không thể thực hiện nó với đồng bằng không chung chung IEnumerable nếu họ nghĩ nó đáng giá).

và không có lý do tại sao bạn không thể cuộn phiên bản của riêng bạn Join mà phải mất một IEnumerable<T> nếu bạn cảm thấy rằng bạn cần nó và bạn không thể nâng cấp lên .NET 4.

+0

... trừ khi một người viết một * mảng-to-'IEnumerable '*, tôi giả sử? Đó là điều mà những người Java của chúng ta thường làm. – Esko

0

Tôi đoán rằng String.Join đòi hỏi khả năng lặp qua mảng hai lần (một lần để đo chiều dài, và một lần để làm bản sao). Một số lớp thực hiện iEnumerable có thể được nối thành công thành một mảng chuỗi bằng cách thực hiện một lần để đếm chiều dài, gọi Reset trên điều tra viên, và sử dụng thẻ thứ hai để sao chép dữ liệu, nhưng vì iEnumerable không hỗ trợ cả thuộc tính Capabilities hay gia đình của các lớp dẫn xuất như iMultiPassEnumerable, cách duy nhất String.Join có thể chấp nhận một cách an toàn một iEnumerable sẽ là (1) liệt kê một số loại danh sách và chạy tham gia vào đó, (2) đoán kích thước chuỗi đích và phân bổ lại thành cần thiết, hoặc (3) kết hợp các phương pháp tiếp cận, nhóm các chuỗi ngắn thành các cụm lên đến ví dụ 8K, và sau đó kết hợp tất cả các cụm vào một kết quả cuối cùng (đó sẽ là một hỗn hợp của các cụm trước khi nối và các chuỗi dài từ mảng ban đầu).

Mặc dù tôi chắc chắn sẽ cho phép String.Join có thể chuyển đổi một iEnumerable thành Danh sách, tôi không thấy rằng nó sẽ cung cấp hiệu quả hơn so với thực hiện chuyển đổi theo cách thủ công (không giống như phiên bản mảng của String.Join, có hiệu quả hơn việc ghép nối các chuỗi riêng theo cách thủ công).

Các vấn đề liên quan