2009-08-27 27 views
18

Tôi có một MyClass lớp, và tôi muốn ghi đè lên các ToString() phương pháp của các trường hợp liệt kê:ToString Overriding() của Danh sách <MyClass>

class MyClass 
{ 
    public string Property1 { get; set; } 
    public int Property2 { get; set; } 
    /* ... */ 
    public override string ToString() 
    { 
     return Property1.ToString() + "-" + Property2.ToString(); 
    } 
} 

Tôi muốn có những điều sau đây:

var list = new List<MyClass> 
      { 
       new MyClass { Property1 = "A", Property2 = 1 }, 
       new MyClass { Property1 = "Z", Property2 = 2 }, 
      }; 

Console.WriteLine(list.ToString()); /* prints: A-1,Z-2 */ 

Có thể làm như vậy không? Hoặc tôi sẽ phải phân lớp Danh sách < MyClass> để ghi đè lên phương thức ToString() trong phân lớp của tôi? Tôi có thể giải quyết vấn đề này bằng cách sử dụng các phương thức mở rộng (tức là, nó có thể ghi đè lên một phương thức với một phương thức mở rộng) không?

Cảm ơn!

+0

Để biết thông tin: Tôi đã cố gắng làm một cái gì đó liên quan đến NHibernate, và ánh xạ các bộ sưu tập trong một chuỗi tuần tự mà có thể phù hợp với một cột duy nhất. Tuy nhiên tôi tìm thấy một cách khác để làm điều đó, bằng cách thực hiện IUserType của riêng tôi và việc triển khai của tôi sẽ tạo chuỗi như tôi cần! Cảm ơn mọi người đã trả lời dù sao đi nữa! –

Trả lời

21

Bạn cần phải phân lớp để ghi đè bất kỳ phương thức nào. Điểm của generics là để nói rằng bạn muốn cùng một hành vi bất kể loại T. Nếu bạn muốn hành vi khác nhau cho một loại T cụ thể thì bạn đang phá vỡ hợp đồng đó và sẽ cần phải viết lớp của riêng bạn:

public class MyTypeList : List<MyClass> 
{ 
    public override string ToString() 
    { 
     return ... 
    } 
} 

Edited thêm:

không, bạn không thể ghi đè lên một phương pháp bằng cách tạo ra một phần mở rộng, nhưng bạn có thể tạo ra một phương pháp mới với một chữ ký khác nhau đó là đặc trưng cho loại danh sách này:

public static string ExtendedToString(this List<MyClass> list) 
{ 
    return .... 
} 

Được sử dụng với

tôi vẫn nghĩ rằng bạn nên subclassing dù ...

+1

Đây là quá ít mã cho lớp danh sách mới, vì vậy tôi sẽ bao gồm nó trên đầu trang trong cùng một tệp mã như lớp 'MyClass'. Vì vậy, đây không phải là rất nhiều nỗ lực để làm, ngay cả khi nó có vẻ phức tạp để tạo ra một lớp mới, nó thực sự không phải là vì hầu hết các chức năng được thừa hưởng từ lớp 'List' ... – awe

+0

** Giới thiệu về việc mở rộng Phương pháp: ** Tôi đồng ý rằng trong trường hợp này bạn nên đi với lớp con, bởi vì phương thức 'ToString' là một cách hợp lý những gì bạn muốn, và' List' không có thực thi mặc định rất hữu ích. Tiện ích mở rộng sẽ thêm phương thức mới và để phương thức 'ToString' ở đó cũng vô dụng vì nó có allways cho lớp' List' chung. – awe

0

Bạn sẽ phải tạo lớp tùy chỉnh của riêng bạn mà kế thừa từ Collection và sau đó overwride phương pháp ToString() của lớp đó đặc biệt.

2

Nếu phương pháp của bạn phải được đặt tên ToString, bạn sẽ phải lấy được một lớp học từ List. Bạn có thể làm cho nó một generic:

static class MyList<T> : List<T> 
{ 
    public override string ToString() 
    { 
     // ... 
    } 
} 

Trong trường hợp này, bạn sẽ phải sử dụng MyList thay vì List suốt ứng dụng của bạn nếu bạn muốn có chuyển đổi tùy chỉnh của bạn.

Tuy nhiên, nếu bạn có thể chọn một tên khác nhau cho phương pháp của bạn, bạn có thể sử dụng phương pháp mở rộng và đạt được hiệu quả tương tự, với hầu như không có thay đổi mã của bạn:

Bạn có thể sử dụng phương pháp khuyến nông để làm điều này chung chung hơn :

static class ListExtension 
{ 
    public static void ConvertToString<T>(this IEnumerable<T> items) 
    { 
     // ... 
    } 
} 

Bạn có thể sử dụng nó trên bất kỳ trường hợp IEnumerable<T> chỉ như thể nó là một phương pháp thông thường:

List<MyClass> list = new List<MyClass> { ... }; 
Console.WriteLine(list.ConvertToString()); 

int[] array_of_ints = {1,2,3,4,5}; 
Console.WriteLine(array_of_ints.ConvertToString()); 
0

không nó không p có thể. ToString của TList sẽ cho bạn biểu diễn chuỗi của đối tượng danh sách.

lựa chọn của bạn là:

  • xuất phát từ TList và ghi đè lên các phương pháp ToString() như bạn đề cập.(trong ví dụ này tôi sẽ không nói giá trị của nó làm như vậy)
  • Tạo phương thức trợ giúp chuyển đổi danh sách TList thành chuỗi được phân tách bằng dấu phẩy, ví dụ: phương pháp mở rộng (có thể là gợi ý tốt nhất)
  • Sử dụng tuyên bố foreach ở giai đoạn Console.WriteLine.

Hy vọng điều đó sẽ hữu ích!

21

Có lẽ một chút ngoài chủ đề, nhưng tôi sử dụng phương thức mở rộng ToDelimitedString hoạt động cho bất kỳ IEnumerable<T> nào. Bạn có thể (tùy chọn) xác định dấu phân cách để sử dụng và một đại biểu để thực hiện một chuyển đổi chuỗi tùy chỉnh cho mỗi yếu tố:

// if you've already overridden ToString in your MyClass object... 
Console.WriteLine(list.ToDelimitedString()); 
// if you don't have a custom ToString method in your MyClass object... 
Console.WriteLine(list.ToDelimitedString(x => x.Property1 + "-" + x.Property2)); 

// ... 

public static class MyExtensionMethods 
{ 
    public static string ToDelimitedString<T>(this IEnumerable<T> source) 
    { 
     return source.ToDelimitedString(x => x.ToString(), 
      CultureInfo.CurrentCulture.TextInfo.ListSeparator); 
    } 

    public static string ToDelimitedString<T>(
     this IEnumerable<T> source, Func<T, string> converter) 
    { 
     return source.ToDelimitedString(converter, 
      CultureInfo.CurrentCulture.TextInfo.ListSeparator); 
    } 

    public static string ToDelimitedString<T>(
     this IEnumerable<T> source, string separator) 
    { 
     return source.ToDelimitedString(x => x.ToString(), separator); 
    } 

    public static string ToDelimitedString<T>(this IEnumerable<T> source, 
     Func<T, string> converter, string separator) 
    { 
     return string.Join(separator, source.Select(converter).ToArray()); 
    } 
} 
+0

Đề xuất tốt nói chung: Tôi cũng sử dụng một phương pháp mở rộng như vậy. Tùy thuộc vào ngữ cảnh chính xác của câu hỏi ban đầu, điều này có thể hoặc không phải là câu trả lời hợp lệ tại đây. – peSHIr

+0

Đây là một số phương pháp tiện ích thực sự tiện dụng, cảm ơn! Giúp tôi tải bên trong một hàm bằng cách sử dụng IList của các loại enum ẩn danh để chuyển đổi chúng thành danh sách phân cách bằng dấu phẩy, chỉ được sử dụng (x => ((ngắn) Convert.ChangeType (x, TypeCode.Int16)) làm tham số chuyển đổi của tôi. một lần nữa Luke –

+0

Theo bình luận danrichardson, cảm ơn cho đầu vào này là khá hữu ích –

0

Tùy thuộc vào lý do chính xác mà bạn có vì muốn ghi đè List<T>.ToString() trở về một cái gì đó cụ thể nó có thể là tiện dụng để xem xét triển khai TypeConverter tùy chỉnh.

Nếu bạn chỉ muốn một List<T> của cụ T để hiển thị bản thân một cách nào đó như một string ở những nơi TypeConverters được sử dụng, giống như trong trình gỡ lỗi hoặc trong tình huống string.Format("List: {0}", listVariable) loại, điều này có thể là đủ.

Bạn có thể đã thấy kết quả của ToString() được hiển thị ở đâu đó và muốn thay đổi điều đó mà không biết về sự tồn tại của TypeConverter và vị trí chúng được sử dụng. Tôi tin rằng nhiều/hầu hết/tất cả (không chắc chắn?) Của TypeConverters mặc định trong Khuôn khổ .NET chỉ cần sử dụng ToString() khi chuyển đổi bất kỳ loại nào mà chúng được xác định cho một string.

2

Bạn thực sự có thể sử dụng thủ thuật unicode để cho phép bạn xác định phương thức ToString thay thế trực tiếp với danh sách chung của bạn.

Nếu bạn kích hoạt hex nhân vật đầu vào visual studio sau đó bạn có thể tạo nhân vật vô hình bằng cách giữ phím Alt, sau đó nhấn sau đây trên bàn phím số của bạn + FFF 9 (nay là nhả phím Alt)

Vì vậy, chúng ta có thể tạo ra các chức năng sau đây với một nhân vật vô hình được đặt bên cạnh tên của nó ... (yes i biết mã VB của nó, nhưng khái niệm này sẽ vẫn làm việc làm việc cho C#)

<Extension()> _ 
Public Function ToString(ByVal source As Generic.List(Of Char)) As String 
    Return String.Join(separator:="", values:=source.ToArray) 
End Function 

Bây giờ trong visual studio, khi bạn truy cập IntelliSense chống lại danh sách của bạn, bạn sẽ có thể lựa chọn giữa một trong hai tiêu chuẩn ToString hoặc chức năng tùy chỉnh của bạn.


Để kích hoạt hex nhân vật đầu vào visual studio bạn có thể cần phải chỉnh sửa registry của bạn

mở HKEY_CURRENT_USER \ Control Panel \ Input Method và tạo ra một REG_SZ gọi EnableHexNumpad thiết lập này đến 1

Bạn cũng sẽ cần tắt phím tắt & cho các menu Tệp, Chỉnh sửa, Gỡ lỗi, Dữ liệu, Trong studio trực quan, mở menu công cụ, chọn tùy chỉnh, sau đó mở tab lệnh và sử dụng nút sửa đổi lựa chọn cho bất kỳ mục menu nào sử dụng ABCDEF charactes cho cắt ngắn của nó, bằng cách loại bỏ các &

Nếu không, bạn sẽ kết thúc mở menu bật lên, thay vì nhập ký tự hex.

+0

này là kinh tởm và câu trả lời của bạn nên được xóa cho tất cả vĩnh cửu .... +1 –

+1

Idk nếu nó hoạt động, nhưng âm thanh khéo léo và đã cho tôi một tốt cười khúc khích! +1 –

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