2012-11-04 17 views
7
 var sample = new 
     { 
      Time = DateTime.Now, 
      Name = "Hello" 
     }; 
     Trace.TraceInformation("{0}", sample); 

kết quả đầu ra nhưOverride ToString() thực hiện mang tính chất đối tượng

Thông tin ProcessInvocation86.exe: 0: {Time = 2012/04/11 22:07:52, Tên = Xin chào}

Tôi muốn định dạng khác trong ứng dụng của mình. Có cách nào để thay đổi việc thực hiện các ToString() cho các đối tượng vô danh trong C#? Có lẽ một số trường tĩnh trên AppDomain hoặc một cái gì đó?

+1

Có lẽ không phải cho các kiểu nặc danh. Khi bạn bắt đầu di chuyển từ một cấu trúc dữ liệu đơn giản đến một đối tượng hơi phong phú hơn, cho thấy chức năng (chẳng hạn như ghi đè phương thức), bạn sẽ cần xác định một loại rõ ràng. – David

+1

Tôi đã thực hiện điều này: 'var sample = new {Time = DateTime.Now, Name =" Hello ", ToString = new Func (() => {return" xxx ";})}; Console.WriteLine (" {0} ", sample.ToString());'. Unfortunatelly có vẻ như không có cách nào để truy cập 'this' từ ToString Func, vì vậy nó có thể chỉ trả về hằng số hoặc biến toàn cầu - vô dụng tôi đoán: ( – Ondra

Trả lời

8

Không, bạn không thể thực hiện việc này - ToString, EqualsGetHashCode được triển khai mặc định do khung công tác cung cấp. Để ghi đè chức năng này, bạn nên kế thừa từ loại ẩn danh của mình, điều này là không thể.

Sử dụng String.Format để có được kết quả mong muốn.

+3

Tôi sẽ thêm rằng nếu bạn cần loại chức năng này, bạn nên xác định lớp thực và mở rộng nó cho phù hợp. –

+0

@JonathonReinhart yep, vừa viết bản cập nhật này! –

4

Theo như nhận thức, không có cách nào để ghi đè hành vi mặc định ToString.
Có thể là giá trị xem xét một số các bài viết từ Eric Lippert về các loại vô danh: http://blogs.msdn.com/b/ericlippert/archive/tags/anonymous+types/

Có lẽ tốt nhất để tạo ra một lớp đơn giản cho mục đích này:

ví dụ

public class MyClass 
{ 
    public DateTime Time { get; set; } 
    public string Name { get; set; } 

    public override string ToString() 
    { 
    return string.Format("Time = {0}. Name = {1}.", Time, Name); 
    } 
} 
1

Tôi biết, một số người thực sự sẽ đấm tôi cho giải pháp như vậy và tôi đồng ý rằng bạn không nên sử dụng nó trong sản xuất. Nếu bạn có chức năng cụ thể cho một số nhóm dữ liệu - điều này chắc chắn nên đi đến lớp riêng biệt. Nhưng đối với các vấn đề nhỏ, bạn có thể sử dụng một chút suy nghĩ như thế này để viết một số định dạng tuỳ chỉnh (Tôi nhắc lại, tôi không gợi ý để sử dụng nó trong sản xuất):

private string FormatProperties<T> (T obj) 
{ 
    string result = ""; 
    var type = typeof(T); 
    foreach (var prop in type.GetProperties()) 
    { 
     result += string.Format("{0}:{1}\r\n", prop.Name, prop.GetValue(obj)); 
    } 
    return result; 
} 

Sau đó, các cuộc gọi

var anon = new {Name = "Ilya", Surname = "Ivanov"}; 
Console.WriteLine (FormatProperties(anon)); 

sẽ dẫn đến in

Name:Ilya 
Surname:Ivanov 

và sau đó bạn có thể cache loại với hiệu suất cao và nhận được vào các loại khác của rắc rối.

0

điều này không chính xác lý tưởng .. nhưng bạn có thể tạo phương thức tiện ích mở rộng có chức năng thực hiện định dạng.

dụ sau định dạng cho LinqPad VÍ DỤ

void Main() 
{ 
var sample = new 
     { 
      Time = DateTime.Now, 
      Name = "Hello", 
     }; 

    sample.ToAnonString(()=>sample.Name).Dump(); 

} 
public static class ovs{ 
     public static string ToAnonString(this object o,Func<string> exp){ 
     return exp(); 
     } 
    } 
Các vấn đề liên quan