2009-05-06 31 views
6

Giả sử tôi có một "Hạng mục" lớp, trong đó có ba biến thành viên: tên chuỗi, số lượng thập phân và đơn vị chuỗi. Tôi đã có các thuộc tính get/set công khai trên cả ba.ToString() cho thuộc tính lớp học?

Đôi khi, tôi muốn hiển thị số lượng dưới dạng văn bản cùng với đơn vị chính xác, ví dụ: 10m hoặc 100 feet.

Câu hỏi của tôi là, có thể có một số loại hàm ToString() cho các thuộc tính để có thể tùy chỉnh đầu ra văn bản của chúng không?

Xin cảm ơn,

Saurabh.

+0

Wow rất nhiều giải pháp!Chọn một câu trả lời trở nên thực sự khó khăn, như IMO, nhiều giải pháp được đề xuất có vẻ chính xác và hữu ích. Hai điểm: 1. Hiện có giao diện người dùng. Tuy nhiên, tôi vẫn muốn làm điều đó "định dạng" bên trong đối tượng, bởi vì nó có vẻ như là vốn có của đối tượng đó, để trả về số lượng của nó cùng với các đơn vị, khi không tham gia vào một số tính toán. 2. Bây giờ, tôi đang đi với giải pháp của Fredrik, vì nó đang cung cấp cho tôi một tài sản sẵn sàng để sử dụng mới, mà không có "phức tạp" của một đối tượng mới cho số lượng + đơn vị. – virtualmic

+0

@virtualmic - Đây có thể là giải pháp đơn giản nhất nhưng tôi không nghĩ đó là giải pháp đúng. Bạn sẽ phải trả thuế bảo trì của các mối quan tâm pha trộn tại một số điểm. –

+0

Cảm ơn bạn Greg, bạn quan tâm. Tôi chắc chắn sẽ thử các cách tiếp cận khác nữa, như bạn và Anton đã gợi ý. Cảm ơn một lần nữa, tất cả mọi người! – virtualmic

Trả lời

13

Những gì bạn có thể làm là để tạo ra một mới (chỉ đọc) tài sản trả lại một phiên bản định dạng:

public string QuantityAsString 
{ 
    get 
    { 
     return string.Format("{0} {1}", this.Quantity, this.Unit); 
    } 
} 
1

Bạn có hai lựa chọn:

  1. Có ToString() của lớp cha mẹ tự động nối các mảnh lại với nhau thành một định dạng tốt đẹp.
  2. Quấn các thuộc tính trong lớp học và cung cấp một ToString() cho những lớp
6

Nói chung , định dạng giá trị cho các đơn vị thích hợp không phải là trách nhiệm của lớp Item. Thay vào đó, điều này nên được thực hiện bởi một số lớp bên ngoài.

Tuy nhiên, nếu bạn thực sự muốn làm định dạng bên trong lớp, tôi khuyên bạn nên xác định một lớp Unit với implicit conversion operators chuyển đổi sang decimal hoặc int s và tất cả các logic định dạng theo yêu cầu.

+0

Tôi đồng ý. Định dạng là một vấn đề lớp trình bày và không được đóng gói trong lớp thực thể lớp miền. – JacobE

+0

Không nhất thiết. Nếu đối tượng có thể làm những điều hợp lý với các đơn vị của nó, chẳng hạn như chuyển đổi giữa chúng, vv, thì đó là một cái gì đó nên rất nhiều trong chính đối tượng. Và ai thậm chí còn nói có một giao diện người dùng? –

+0

@Greg Tại sao sau đó anh ấy muốn "hiển thị số lượng dưới dạng văn bản"? –

2

Tôi nghĩ cách tiếp cận tốt nhất từ ​​quan điểm chất lượng mã là để tạo lớp sẽ bao bọc giá trị với đơn vị và cung cấp .ToString() tại đó.

8

Có vẻ như mô hình đối tượng của bạn không được tính đúng. Những gì bạn có thể muốn làm là trừu tượng UnitQuantity thành một đối tượng khác và sau đó bạn có thể ghi đè lên ToString cho điều đó. Điều này có lợi thế là giữ các giá trị phụ thuộc với nhau và cho phép bạn triển khai những thứ như chuyển đổi giữa các đơn vị trong tương lai (ví dụ: chuyển đổi từ inchest sang feet, v.v.), ví dụ:

public struct Measure 
{ 
    public Measure(string unit, decimal quantity) 
    { 
     this.Unit = unit; 
     this.Quantity = quantity; 
    } 

    public string Unit { get; private set; } 
    public decimal Quantity { get; private set; } 

    public override string ToString() 
    { 
     return string.Format("{0} {1}", this.Quantity, this.Unit); 
    } 
} 

public class Item 
{ 
    public string Name { get; set; } 
    public Measure Measure { get; set; } 

    public override string ToString() 
    { 
     return string.Format("{0}: {1}", this.Name, this.Measure); 
    } 
} 

Lưu ý rằng tôi đã tạo Measure cấu trúc ở đây vì nó có thể có ngữ nghĩa giá trị. Nếu bạn sử dụng phương pháp này, bạn nên làm cho nó không thay đổi và ghi đè Equals/GetHashCode là thích hợp cho một cấu trúc.

1

Bạn có thể thực hiện các giao diện IFormatable có ToString khác nhau của

public class Item : IFormattable 
{ 
    public string Name; 
    public decimal Quantity; 
    public string Unit; 

    public override string ToString(string format, IFormatProvider provider) 
    { 
     switch(format) 
     { 
      case "quantity": return Quantity + Unit; 
      default: return Name; 
     } 
    } 
} 

Điều này có thể được sử dụng như thế này:

Item item = new Item(); 
Console.WriteLine(item.ToString()); 
Console.WriteLine("Quantity: {0:quantity}", item); 
+0

mặc định ở đây có lẽ nên ném một FormatException ... –

+0

Đồng ý, và cần có một trường hợp cho string.Empty hoặc "" quá ... –

0

Một vài ngày trước, tôi thực hiện các mô hình tương tự. Và tôi đã thực hiện các lớp học riêng biệt cho Số lượng và Đơn vị. Có vẻ như điều này (nó được đơn giản hóa, trên thực tế có các nhà thầu và các toán tử quá tải):

class Quantity 
{ 
    public decimal Value; 
    public UnitOfMeasure Unit; 

    public override string ToString() 
    { 
     return string.Format("{0} {1}", Value, Unit); 
    } 
} 

class UnitOfMeasure 
{ 
    public string Name; 

    public override string ToString() { return Name; } 
} 
Các vấn đề liên quan