ToString() 是 .NET 中几乎所有对象都拥有的核心方法,用于将对象转换为其字符串表示形式,它的强大之处在于可以通过不同的重载形式接受参数,从而实现高度自定义的格式化输出。
我们将从以下几个方面来讲解:
- 无参数
ToString() - 接受
IFormatProvider参数的ToString() - 接受
string格式字符串的ToString() - 同时接受
string和IFormatProvider的ToString() - 针对数值类型的特殊格式说明符
- 针对日期时间类型的特殊格式说明符
- 自定义类型的
ToString()重写
无参数 ToString()
这是最简单的用法,它返回对象的默认字符串表示形式。
- 对于基本数据类型:通常返回其数字的文本形式。
int number = 123; Console.WriteLine(number.ToString()); // 输出: 123
- 对于
DateTime:返回一个标准的、可读的日期时间字符串(格式通常是 "G")。DateTime now = DateTime.Now; Console.WriteLine(now.ToString()); // 输出示例: 10/26/2025 10:30:55 AM (具体格式取决于系统区域设置)
- 对于自定义类:如果不重写,它返回该类型的完整限定名(
namespace.classname)。public class MyClass { } MyClass obj = new MyClass(); Console.WriteLine(obj.ToString()); // 输出: YourNamespace.MyClass
接受 IFormatProvider 参数的 ToString()
这个重载允许你指定一个格式化提供程序,它是一个实现了 IFormatProvider 接口的对象,这个对象的主要作用是提供与区域化(文化)相关的信息,比如数字的小数点符号、千位分隔符、货币符号、日期时间格式等。
- 核心接口:
IFormatProvider- 它有一个关键方法:
GetFormat(Type formatType)。 - 当
ToString()需要特定格式的信息时(如数字格式),它会调用GetFormat方法,并请求特定类型的格式化器(如NumberFormatInfo或DateTimeFormatInfo)。
- 它有一个关键方法:
- 常用实现:
CultureInfo: 最常用的实现,你可以用它来指定不同的文化区域。CultureInfo.InvariantCulture: 不受任何文化影响的“中性”格式,常用于日志、序列化等需要稳定输出的场景。CultureInfo.GetCultureInfo("zh-CN"): 中国大陆文化,数字格式如1,234.56,日期格式如2025/10/26。CultureInfo.GetCultureInfo("en-US"): 美国文化,数字格式如1,234.56,日期格式如10/26/2025。CultureInfo.GetCultureInfo("fr-FR"): 法国文化,数字格式如1 234,56。
示例:
double price = 12345.67;
// 使用美国文化
var usCulture = CultureInfo.GetCultureInfo("en-US");
Console.WriteLine(price.ToString("C", usCulture)); // 输出: $12,345.67 (C 是货币格式)
// 使用中国大陆文化
var cnCulture = CultureInfo.GetCultureInfo("zh-CN");
Console.WriteLine(price.ToString("C", cnCulture)); // 输出: ¥12,345.67
// 使用不变文化
Console.WriteLine(price.ToString("C", CultureInfo.InvariantCulture)); // 输出: 12,345.67
接受 string 格式字符串的 ToString()
这是最常用和最强大的重载之一,你通过一个 string 参数来定义你想要的输出格式。
这个格式字符串由格式说明符和精度说明符组成。
- 格式说明符:一个或多个字符,定义了值的总体格式(如货币、科学计数法、十六进制等)。
- 精度说明符:跟在格式说明符后面的数字,定义了输出中要显示的有效位数或小数位数。
数值类型常用格式说明符:
| 说明符 | 名称 | 描述 | 示例 (5678) |
|---|---|---|---|
| C | Currency | 货币格式 | 5678.ToString("C") -> $1,234.57 |
| D | Decimal | 十进制格式,需要整数。 | ToString("D6") -> 000123 |
| E | Exponential (科学计数法) | 科学计数法格式 | 6789.ToString("E2") -> 23E+004 |
| F | Fixed-point | 固定点格式,指定小数位数。 | 456.ToString("F2") -> 46 |
| G | General (通用) | 常用格式,默认格式之一。 | 456.ToString("G4") -> 5 |
| N | Number | 数字格式,包含千位分隔符。 | ToString("N2") -> 1,234,567.00 |
| P | Percent | 百分比格式,值会乘以100。 | 1234.ToString("P1") -> 3 % |
| X | Hexadecimal | 十六进制格式,需要整数。 | ToString("X") -> FF |
示例:
double number = 12345.6789;
// 货币格式,保留2位小数
Console.WriteLine(number.ToString("C")); // 输出: $12,345.68 (取决于系统文化)
// 固定点格式,保留3位小数
Console.WriteLine(number.ToString("F3")); // 输出: 12345.679
// 数字格式,带千位分隔符,保留1位小数
Console.WriteLine(number.ToString("N1")); // 输出: 12,345.7
// 百分比格式
Console.WriteLine(number.ToString("P")); // 输出: 1,234,567.89 %
// 十六进制
int integer = 255;
Console.WriteLine(integer.ToString("X")); // 输出: FF
同时接受 string 和 IFormatProvider 的 ToString()
这是最完整的重载,它允许你同时指定格式字符串和格式化提供程序,这让你可以精确控制输出内容的格式和区域化样式。
语法: object.ToString(string format, IFormatProvider provider)
示例:
double value = 12345.6789;
// 格式化为固定点,保留2位小数,并使用法国文化
var frCulture = CultureInfo.GetCultureInfo("fr-FR");
string result = value.ToString("F2", frCulture);
Console.WriteLine(result); // 输出: 12345,68 (注意逗号作为小数点)
// 格式化为货币,并使用德国文化
var deCulture = CultureInfo.GetCultureInfo("de-DE");
string currencyResult = value.ToString("C", deCulture);
Console.WriteLine(currencyResult); // 输出: 12.345,68 €
针对日期时间类型的特殊格式说明符
DateTime 和 TimeSpan 类型也支持格式字符串,但说明符的含义不同。
| 说明符 | 示例 (2025-10-26 15:30:55) |
|
|---|---|---|
| d | 短日期模式 | 10/26/2025 |
| D | 长日期模式 | Thursday, October 26, 2025 |
| t | 短时间模式 | 3:30 PM |
| T | 长时间模式 | 3:30:55 PM |
| f | 完整日期/时间(短时间) | Thursday, October 26, 2025 3:30 PM |
| F | 完整日期/时间(长时间) | Thursday, October 26, 2025 3:30:55 PM |
| g | 常规日期/时间(短时间) | 10/26/2025 3:30 PM |
| G | 常规日期/时间(长时间) | 10/26/2025 3:30:55 PM |
| M, m | 月日模式 | October 26 |
| y, Y | 年月模式 | October 2025 |
| (自定义) | 自定义模式 | yyyy-MM-dd HH:mm:ss -> 2025-10-26 15:30:55 |
自定义模式: 你可以使用特定的占位符来构建自己的日期时间格式。
| 占位符 | 含义 |
|---|---|
| yyyy | 4位数年份 |
| yy | 2位数年份 |
| MM | 2位数月份 (01-12) |
| M | 1或2位数月份 (1-12) |
| dd | 2位数日期 (01-31) |
| d | 1或2位数日期 (1-31) |
| HH | 24小时制的小时 (00-23) |
| hh | 12小时制的小时 (01-12) |
| mm | 分钟 (00-59) |
| ss | 秒 (00-59) |
| tt | AM/PM 指示符 |
示例:
DateTime now = new DateTime(2025, 10, 26, 15, 30, 55);
// 使用标准格式说明符
Console.WriteLine(now.ToString("f")); // 输出: Thursday, October 26, 2025 3:30 PM
// 使用自定义格式字符串
Console.WriteLine(now.ToString("yyyy-MM-dd")); // 输出: 2025-10-26
Console.WriteLine(now.ToString("yyyyMMdd_HHmmss")); // 输出: 20251026_153055 (常用于文件名)
Console.WriteLine(now.ToString("dddd, MMMM d, yyyy")); // 输出: Thursday, October 26, 2025
针对自定义类型的 ToString() 重写
当你创建自己的类或结构时,你可以重写 ToString() 方法,为你的对象提供一个更有意义、更易读的默认字符串表示。
如何重写:
使用 override 关键字。
示例:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int Age { get; set; }
// 重写 ToString() 方法
public override string ToString()
{
// 提供一个友好的默认表示
return $"{LastName}, {FirstName} (Age: {Age})";
}
}
// 使用
Person person = new Person { FirstName = "John", LastName = "Doe", Age = 30 };
Console.WriteLine(person);
// 输出: Doe, John (Age: 30)
// 注意:直接 Console.WriteLine(person) 会自动调用 person.ToString()
你甚至可以重写接受 string 格式参数的版本,让你的自定义对象也支持格式化。
public class Person
{
// ... 属性同上 ...
public override string ToString()
{
return ToString("F"); // 默认调用带格式的版本
}
public string ToString(string format)
{
if (string.IsNullOrEmpty(format)) format = "F";
switch (format.ToUpper())
{
case "F": // Full name
return $"{FirstName} {LastName}";
case "L": // Last name only
return LastName;
case "A": // Age only
return Age.ToString();
default:
throw new FormatException($"Invalid format string: '{format}'");
}
}
}
// 使用
Person p = new Person { FirstName = "Jane", LastName = "Smith", Age = 28 };
Console.WriteLine(p.ToString()); // 输出: Jane Smith
Console.WriteLine(p.ToString("F")); // 输出: Jane Smith
Console.WriteLine(p.ToString("L")); // 输出: Smith
Console.WriteLine(p.ToString("A")); // 输出: 28
| 参数 | 用途 | 核心概念 |
|---|---|---|
| 无参数 | 获取对象的默认字符串表示。 | 默认行为 |
IFormatProvider |
控制区域化相关的格式(小数点、货币符号等)。 | CultureInfo, InvariantCulture |
string 格式字符串 |
定义输出的具体格式(货币、科学计数、日期时间模式等)。 | 格式说明符 (C, D, F, N, X...) 和 精度说明符 |
| 两者都有 | 同时控制格式和区域化,实现最精确的输出控制。 | 组合使用 |
重写 ToString() |
为自定义类型提供有意义的默认或可格式化字符串。 | override 关键字,自定义逻辑 |
掌握 ToString() 的各种参数用法,是进行 .NET 开发中数据展示、日志记录、文件命名、用户界面交互等任务的基础技能。
