String.Format - cách hoạt động và cách triển khai các chuỗi định dạng tùy chỉnh


79

Với String.Format()nó có thể định dạng DateTimecác đối tượng ví dụ theo nhiều cách khác nhau. Mỗi khi tôi tìm kiếm một định dạng mong muốn, tôi cần phải tìm kiếm trên Internet. Hầu như tôi luôn tìm thấy một ví dụ mà tôi có thể sử dụng. Ví dụ:

String.Format("{0:MM/dd/yyyy}", DateTime.Now);          // "09/05/2012"

Nhưng tôi không có bất kỳ manh mối nào về cách nó hoạt động và lớp nào hỗ trợ các chuỗi bổ sung 'ma thuật' này.

Vì vậy, câu hỏi của tôi là:

  1. Làm thế nào để String.Formatánh xạ thông tin bổ sung MM/dd/yyyyvào một kết quả chuỗi?
  2. Tất cả các đối tượng của Microsoft có hỗ trợ tính năng này không?
    Điều này có được ghi ở đâu đó không?
  3. Có thể làm điều gì đó như thế này không:
    String.Format("{0:MyCustomFormat}", new MyOwnClass())

Câu trả lời:


88

String.Formatkhớp từng mã thông báo bên trong chuỗi ( {0}v.v.) với đối tượng tương ứng: http://msdn.microsoft.com/en-us/library/system.string.format.aspx

Một chuỗi định dạng được cung cấp tùy chọn:

{ index[,alignment][ : formatString] }

Nếu formatStringđược cung cấp, đối tượng tương ứng phải triển khai IFormattable và cụ thể là ToStringphương thức chấp nhận formatStringvà trả về chuỗi được định dạng tương ứng: http://msdn.microsoft.com/en-us/library/system.iformattable.tostring.aspx

Một IFormatProvidercũng có thể được sử dụng có thể được sử dụng để nắm bắt các tiêu chuẩn / mặc định định dạng cơ bản, v.v. Ví dụ ở đâyở đây .

Vì vậy, câu trả lời cho câu hỏi của bạn theo thứ tự:

  1. Nó sử dụng phương thức IFormattablecủa giao diện ToString()trên DateTimeđối tượng và chuyển MM/dd/yyyychuỗi định dạng đó. Đó là việc triển khai trả về chuỗi chính xác.

  2. Bất kỳ đối tượng nào triển khai đều IFormattablehỗ trợ tính năng này. Bạn thậm chí có thể viết của riêng bạn!

  3. Có, xem ở trên.


10
+1 để liên kết đến tài liệu . "Tìm kiếm trên internet" có thể được. Nhưng khi cần hiểu sâu hơn, bạn nên Đọc Hướng dẫn sử dụng.
MarkJ

Câu trả lời hay nhưng bạn có thể cho tôi biết tôi có thể tìm thấy ở đâu cho mỗi lớp triển khai IFormattable, nơi tôi có thể tìm thấy các Chuỗi định dạng được phép không. Ví dụ: hỗ trợ DateTime (trên đầu tôi) y M d h m svà hơn thế nữa. Các kiểu số hỗ trợ Ctừ tiền tệ nhưng đó không phải là tất cả những gì tôi biết từ việc tìm kiếm arround và không phải bằng cách xem tài liệu của Microsoft.
hwcverwe

@hwcverwe - gần như bất kỳ tìm kiếm nào của Google sẽ đặt tài liệu MSDN ở hoặc gần đầu tìm kiếm bất kỳ đối tượng nào. Sẽ không có trang nào hiển thị ToString (...) cho mọi đối tượng - có khả năng là "vô hạn" trong số đó, bởi vì theo mặc định, tất cả các đối tượng đều triển khai ít nhất ToString (), mặc dù không nhất thiết phải là ToString (định dạng).
Wonko the Sane


20

Theo hiểu biết của tôi, bạn sẽ cần triển khai IFormattable trong lớp của mình để hỗ trợ điều này. Sau đó, có phương thức, ToString, lấy các tham số bạn truyền vào String.Format.

Đây là một ví dụ.

// Define other methods and classes here
public class Sample : IFormattable
{
     public string ToString(string format, IFormatProvider provider)
     {
         return String.Concat("Your custom format was ", format);
     }
}

String.Format("{0:MyCustomFormat}", new Sample())

5
  1. Kiểm tra tài liệu MSDN chính thức, có danh sách đầy đủ các chuỗi định dạng DateTime ở đây: http://msdn.microsoft.com/en-us/library/az4se3k1.aspx . Quả thực có một vài sợi dây khá "thần kỳ".

  2. Theo như tôi biết không phải tất cả các loại đều có định dạng "thú vị", nhưng tất cả các loại đều hỗ trợ ToString(). Nếu bạn cần định dạng một đối tượng được tích hợp sẵn, bạn có thể thêm một phương thức mở rộng để thực hiện việc đó, nhưng thường thì định dạng được cung cấp ở bất kỳ nơi nào cần thiết (hoặc nói một cách khác, tôi chỉ viết các định dạng tùy chỉnh cho các loại của riêng tôi) .

  3. Có, bạn có thể viết của riêng mình và nếu bạn có dữ liệu có thể được định dạng theo các cách khác nhau, bạn có thể nên viết một định dạng tùy chỉnh bằng cách triển khai IFormattable, xem lại tài liệu tại đây: http://msdn.microsoft.com/en-us/ thư viện / system.iformattable.aspx . Nó khá đơn giản, bạn chỉ cần kiểm tra các chuỗi được cung cấp và viết ra dữ liệu của bạn dựa trên những chuỗi này, không có ma thuật nào đằng sau hậu trường :-)


4

Dưới các trang bìa String.Format thực hiện một số việc như sau,

IFormattable formattable = objectToFormat as IFormattable;
if (formattable != null)
{
    formattable.ToString(objectToFormat);
}
else
{
    objectToFormat.ToString();
}

Đối với câu hỏi của bạn,

  1. Làm thế nào để String.Format ánh xạ thông tin bổ sung MM / dd / yyyy thành một kết quả chuỗi?

    Như đã chỉ rõ ở trên, nó chỉ gọi IFormattable .ToString (định dạng chuỗi, nhà cung cấp IFormatProvider). Nhà cung cấp thường là thứ cho bạn biết văn hóa của hệ thống của bạn là gì. Thường là null vì mọi người không chuyển nó vào String.Format () như bạn đã làm trong trường hợp của mình.

  2. Có phải tất cả các đối tượng microsoft đều hỗ trợ tính năng này không? Điều này có được ghi ở đâu đó không?

    Bất cứ điều gì triển khai IFormattable đều không.

  3. Có thể làm điều gì đó như thế này không: String.Format("{0:MyCustomFormat}, new MyOwnClass())

    Về cơ bản nếu bạn muốn đối tượng của riêng mình thực hiện điều gì đó với định dạng được cung cấp mà bạn triển khai IFormattable.

Có một số lượng lớn các lớp và bảng kê hỗ trợ để đảm bảo rằng các chuỗi định dạng phần lớn giống nhau. Thêm ở đây .


0

Có, nó có thể - nó có thể được tùy chỉnh hoàn toàn. Nhìn vào liên kết tài liệu này về định dạng tùy chỉnh ngày và giờ.

Nếu bạn có đối tượng của riêng mình, bạn có quyền ghi đè ToString()phương thức và xuất ra bất cứ thứ gì bạn cho là biểu diễn phù hợp. Khi bạn làm điều này, bạn có thể sử dụng String.Format("{0:MyCustomFormat}", new MyOwnClass())vì điều này ngầm gọiMyOwnClass.ToString()


-1 - OP đang hỏi về nhiều thứ hơn là DateTimeđịnh dạng. Và chỉ một liên kết không phải là một câu trả lời.
Hoạt động

1
Rất khắc nghiệt. DateTime là một trong những khía cạnh và tôi đang mở rộng câu trả lời của mình trong khi bạn phản đối.
Maciej

6
Mở rộng câu trả lời rồi đăng , và bạn sẽ không bị phản đối.
Khai trương

0

Tài liệu về ngày tháng có thể được tìm thấy tại đây: http://msdn.microsoft.com/en-us/library/8kb3ddd4.aspx

Điều đó sẽ cho bạn biết chính xác ý nghĩa của tất cả các ký tự định dạng ngày tháng như MM.

Nếu bạn muốn thay đổi cách một chuỗi được xuất cho một lớp tùy chỉnh, bạn có thể ghi đè phương thức ToString, như sau:

public class User
{
     public string Name { get; set; }
     public int Age { get; set; }

     public override string ToString()
     {
         return this.Name + " is " + this.Age + " years old.";
     }
}

và sau đó bạn chỉ có thể làm một cái gì đó như myUser.ToString()và nhận được kết quả bạn đã chỉ định.


0

Và để trả lời câu hỏi thứ ba của bạn: Điều đó là không thể với cú pháp này, nhưng bạn có thể cung cấp các trường hợp IFormatProviderICustomFormattercho một kiểu bạn không tạo hoặc triển khai IFormattablebên trong kiểu của bạn (mặc dù, về cơ bản thì điều đó mở rộng ToString).

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.