2011-02-03 61 views
32

Tôi có một đối tượng chứa nhiều giá trị, một số trong số chúng (không phải tất cả các giá trị từ đối tượng) cần phải được đặt trong chuỗi csv. Cách tiếp cận của tôi là:Tạo chuỗi phân cách bằng dấu phẩy C#?

string csvString = o.number + "," + o.id + "," + o.whatever .... 

Bằng cách nào đó tôi nghĩ có cách tốt hơn, thanh lịch hơn?

+0

Nói chung nó được coi là kém hiệu quả hơn để nối chuỗi bằng ký hiệu '+'. Nó tạo ra nhiều vật thể hơn để thu gom rác thải. –

+0

[Phân cách bằng dấu phẩy thủ công so với lớp CommaDelimitedStringCollection mát mẻ!] (Http://izlooite.blogspot.com/2009/12/manual-comma-separation-versus-cool.html) –

Trả lời

73

Nếu bạn đặt tất cả giá trị của mình vào một mảng, ít nhất bạn có thể sử dụng string.Join.

string[] myValues = new string[] { ... }; 
string csvString = string.Join(",", myValues); 

Bạn cũng có thể sử dụng sự quá tải của string.Join rằng mất params string như tham số thứ hai như thế này:

string csvString = string.Join(",", value1, value2, value3, ...); 
+0

+1 để sử dụng một mảng ở giữa mã dễ đọc hơn khi có nhiều giá trị "một vài". – Bazzz

+0

@ Bazzz - Có, nó có thể nhanh chóng lộn xộn nếu bạn nhập 10 + tham số vào cuộc gọi phương thức kết nối. Tôi nghĩ cách tiếp cận đầu tiên là phương pháp sạch nhất, nhưng đối với một vài giá trị, phương pháp thứ hai cũng ổn. –

+0

Tại sao hai downvotes trên câu trả lời này? Một lý do sẽ được đánh giá cao để mọi người biết những gì bạn cảm thấy là vấn đề với câu trả lời này. –

1

Bạn có thể ghi đè lên) phương pháp của đối tượng của bạn ToString (:

public override string ToString() 
{ 
    return string.Format ("{0},{1},{2}", this.number, this.id, this.whatever); 
} 
+0

Điều này chỉ hữu ích nếu anh ta biết chính xác số lượng phần tử mà anh ta muốn đặt trong chuỗi. string.Join có lẽ phù hợp hơn. –

+0

Có nhưng vì anh ấy muốn tạo tệp csv, các yếu tố có nhiều khả năng sẽ giống nhau mỗi lần. Tôi không biết, đó là vấn đề ưu tiên. –

+0

Tôi giả định từ câu hỏi rằng anh ấy luôn luôn muốn cùng một lĩnh vực để chắc chắn anh ta biết số lượng các yếu tố. Không có gì sai với câu trả lời này mặc dù tôi không thực sự thích trọng ToString ở đây vì nó có thể không được mục đích chung đủ. 1 từ tôi anyway. – fearofawhackplanet

3

Bạn có thể sử dụng phương thức string.Join để thực hiện điều gì đó như string.Join(",", o.Number, o.Id, o.whatever, ...).

chỉnh sửa: Như digEmAll đã nói, string.Join nhanh hơn StringBuilder. Họ sử dụng một thực hiện bên ngoài cho chuỗi.Join.

Profiling mã (tất nhiên chạy trong phiên bản không có ký hiệu debug):

class Program 
{ 
    static void Main(string[] args) 
    { 
     Stopwatch sw = new Stopwatch(); 
     string r; 
     int iter = 10000; 

     string[] values = { "a", "b", "c", "d", "a little bit longer please", "one more time" }; 

     sw.Restart(); 
     for (int i = 0; i < iter; i++) 
      r = Program.StringJoin(",", values); 
     sw.Stop(); 
     Console.WriteLine("string.Join ({0} times): {1}ms", iter, sw.ElapsedMilliseconds); 

     sw.Restart(); 
     for (int i = 0; i < iter; i++) 
      r = Program.StringBuilderAppend(",", values); 
     sw.Stop(); 
     Console.WriteLine("StringBuilder.Append ({0} times): {1}ms", iter, sw.ElapsedMilliseconds); 
     Console.ReadLine(); 
    } 

    static string StringJoin(string seperator, params string[] values) 
    { 
     return string.Join(seperator, values); 
    } 

    static string StringBuilderAppend(string seperator, params string[] values) 
    { 
     StringBuilder builder = new StringBuilder(); 
     builder.Append(values[0]); 
     for (int i = 1; i < values.Length; i++) 
     { 
      builder.Append(seperator); 
      builder.Append(values[i]); 
     } 
     return builder.ToString(); 
    } 
} 

string.Join mất 2ms trên máy tính và StringBuilder.Append 5ms tôi. Vì vậy, có sự khác biệt đáng chú ý. Nhờ digAmAll cho gợi ý.

+2

'string.Join' nhanh bằng' StringBuilder' (nếu không nhanh hơn một chút) vì cả hai chỉ phân bổ một chuỗi duy nhất – digEmAll

+0

Vấn đề với chuỗi ký tự bình thường (ví dụ: using string1 + = string2) là rằng chuỗi gốc1 bị vứt bỏ (vì các chuỗi là bất biến), và tổng mới của chuỗi1 và chuỗi2 được chỉ bởi chuỗi1, và điều đó không hiệu quả nếu được thực hiện nhiều lần. Tuy nhiên, như digEmAll cũng chỉ ra, string.Join tất nhiên chỉ phân bổ chuỗi một lần. Không một lần cho mỗi phần tử trong mảng. –

+0

Một bất lợi của 'string.Join' (cho đến .NET 4.0) là nó đòi hỏi một mảng các chuỗi, buộc bạn phải cấp phát một chuỗi nếu bạn chỉ có một' IEnumerable 'chung nào đó ... anyway .NET 4.0 đã khắc phục vấn đề này – digEmAll

1

Nếu bạn đang sử dụng Net 4 bạn có thể sử dụng sự quá tải cho string.Join mà phải mất một IEnumerable nếu bạn có chúng trong một danh sách, quá:

string.Join(", ", strings); 
6

cách tiếp cận khác là sử dụng lớp CommaDelimitedStringCollection từ Hệ thống .Cấu hình không gian tên/assembly. Nó hoạt động giống như một danh sách cộng với nó có một phương thức ToString được ghi đè trả về một chuỗi được phân tách bằng dấu phẩy.

Ưu điểm - Linh hoạt hơn mảng.

Nhược điểm - Bạn không thể chuyển một chuỗi chứa dấu phẩy.

CommaDelimitedStringCollection list = new CommaDelimitedStringCollection(); 

list.AddRange(new string[] { "Huey", "Dewey" }); 
list.Add("Louie"); 
//list.Add(","); 

string s = list.ToString(); //Huey,Dewey,Louie 
Các vấn đề liên quan