2010-02-16 25 views
5

Điều tôi đang làm là tra cứu giá trị cho một trường cụ thể trong thẻ bắt đầu bằng #. Đối tượng có thể là một số ít các kiểu nguyên thủy mà giá trị của nó được đặt bên trong XML nhưng nó xuất phát từ đối tượng có thể bắt đầu bằng. Vì vậy, tôi có vấn đề cần phải quyết định loại là gì, bỏ nó lên và sau đó sử dụng loại ToString đó. Sẽ tốt hơn nếu tôi không cần phải bỏ nó nhưng sau đó nó sẽ gọi ToString trên kiểu đối tượng và không phải là phương thức đối tác trên loại thực tế.Cách thức sạch sẽ để truyền tới một đối tượng thực tế là

Mã sau đây có chức năng chính xác, nhưng tôi không cảm thấy thoải mái với nó. Có lẽ theo con đường thoải mái này sẽ dẫn đến tôi là một người thuần túy. Dù bằng cách nào tôi sẽ rất nhiều đánh giá cao một cách đẹp hơn để viết này nếu như vậy tồn tại.

public string GetColumnValue(string columnName) 
     { 
      object value = item[columnName]; 

      if (value == null) 
       return string.Empty; 

      if (value.GetType() == typeof(string)) 
      { 
       return (string)value; 
      } 
      else if (value.GetType() == typeof(double)) 
      { 
       return ((double)value).ToString(); 
      } 
      ... 
     } 

Trả lời

8

Nếu tất cả các bạn đang làm là gọi ToString, do tính chất đa hình của C#, các ToString sẽ gọi thực hiện đúng, ngay cả khi tất cả các bạn có là một tham chiếu đến đối tượng.

ví dụ .:

var d=DateTime.Now; 
object od=d; 
Console.WriteLine(od.ToString()); 
Console.WriteLine(d.ToString()); //same as previous line 
+1

Điều này làm việc cho các loại cơ bản, nhưng có thể không hoạt động tốt cho các loại tùy chỉnh - phụ thuộc vào những gì có thể được trả lại trong mục [columnName] ... –

+0

Reed, bạn có thể đưa ra ví dụ không? – spender

+0

Tôi thành thật không nghĩ rằng điều này sẽ làm việc. Vì vậy, đối với lợi ích của đối số, làm thế nào bạn có thể gọi một cách rõ ràng một thực thi ToString trên một kiểu cây thừa kế cụ thể? –

1

Tùy thuộc vào danh sách các loại chấp nhận được, bạn có thể muốn xem xét sử dụng Convert.ToString và/hoặc IConvertable interface.

Điều này sẽ cho phép bạn xử lý hầu hết các loại nguyên thủy trong một lần chụp.

Tuy nhiên, bạn vẫn cần xử lý séc trống của mình.

0

Tại sao bạn không thể sử dụng .ToString() trên value kể từ khi .ToString() được kế thừa từ đối tượng? Các. ToString() cho loại thích hợp hơn nữa lên chuỗi thừa kế sẽ được gọi.

+0

Tuy nhiên, vẫn cần kiểm tra null. –

1

chỉnh sửa

mã thử nghiệm đang ở đây nếu có ai quan tâm: http://gist.github.com/raw/305787/dc5349d9f6fa37ee5d621b43ec92dade60fe1c8d/ToStringTests.cs

Dưới đây bạn sẽ tìm thấy câu trả lời ban đầu của tôi. Có người chỉ ra rằng bạn có thể có một loại mà không có một ToString() bạn thích (vì nó sử dụng Object hoặc một cái gì đó cao hơn trong chuỗi). Cách tốt nhất để xử lý này trong 3.0+ là với một phương pháp mở rộng như thế này:

public static class ToStringExpander 
    { 
     public static string MyToString (this Object x) 
     { 
      return x.ToString(); 
     } 

     public static string MyToString (this mytype x) 
     { 
      return "This is the to string of mytype!"; 
     } 
    } 

Bây giờ MyType sẽ làm việc với GetColumnValue dưới đây nếu bạn thay đổi ToString() để MyToString()

gốc bài

Điều này sẽ làm những gì bạn muốn.

public string GetColumnValue(string columnName) 
    { 
     object value = item[columnName]; 

     if (value == null) 
      return string.Empty; 

     return object.ToString(); 
    } 

hoặc nếu bạn muốn tìm kiếm trường cũ:

public string GetColumnValue(string columnName) 
    { 
     return (item[columnName] == null ? string.Empty : item[columnName].ToString()); 
    } 

của khoá học cũ đúng sẽ được thực hiện một macro #define ...

+1

Quy tắc phân giải tên phương thức yêu cầu các phương thức thành viên của đối tượng được chọn tùy theo bất kỳ phương thức mở rộng nào có thể nằm trong phạm vi. Vì vậy, tôi khá chắc chắn rằng những gì bạn đang đề xuất ở đây sẽ không hoạt động. –

+0

Vâng, tôi vừa thử nghiệm nó, cuốn sách tôi đã đọc ngụ ý nó sẽ hoạt động như tôi mô tả, tôi đã thay đổi câu trả lời cho một giải pháp mới. – Hogan

0

ToString() là một phương pháp ảo. Điều này có nghĩa là bất kỳ cuộc gọi nào đến phương thức đó, vào thời gian chạy, hãy chọn việc triển khai chính xác ("loại có nguồn gốc nhiều nhất"). Vì tất cả các kiểu nguyên thủy ghi đè ToString() để làm điều đúng, không có lý do cho bất kỳ phép đúc nào cho bất kỳ loại biến nào.

Đối với một phương pháp ảo, loại biến không quan trọng trong việc chọn triển khai chính xác. Tất cả những vấn đề đó là kiểu thời gian chạy của đối tượng đang được tham chiếu.

int x = 10; 
object o = x; 
x.ToString(); 
o.ToString(); 

Cả hai cuộc gọi đến ToString() sẽ thực thi cùng mã (trừ unboxing xảy ra trong phiên bản object, vì int là một kiểu giá trị).

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