写这篇文章是来源于一次关于Cast和ConsoleWriteline()的研究。
ConsoleWriteline()是一个在终端输出的简单方法,但是它输出原理是什么?下面给出一个例子。
public struct Currency
{
public uint Dollars { get; }
public ushort Cents { get; }
public Currency(uint dollars, ushort cents)
{
Dollars = dollars;
Cents = cents;
}
public override string ToString() => $"${Dollars}.{Cents,-2:00}";
public static implicit operator string (Currency value) => "Currency";
}
先看ToString()和 public static implicit operator string (Currency value) => “Currency”; 第 一个是重写方法,第二个是隐式转换。
那么调用以下代码输出
Currency balance = new Currency(50, 35);
Console.WriteLine(balance);
Console.WriteLine($"balance is {balance}");
输出结果

可以看出第一个writeline调用了隐式转换,第二个writeline 调用了ToString()方法。
所以其中隐含的代码应该是这样的
Console.WriteLine((string)balance);
Console.WriteLine($"balance is {balance.ToString()}");
但是如果注释掉隐式转换//public static implicit operator string (Currency value) => “Currency”;
输出结果就变成了:

如果注释掉ToString()//public override string ToString() => """{Dollars}.{Cents,-2:00}";
输出结果就变成了:

所以这里揭示了两个规则,第一,隐式转换优先级高于ToString()方法,WriteLine(balance)先检查隐式转换符是否存在,如果不存在则调用ToString()方法。第二,$相当于String.Format()简化,String.Format()里面的参数并不会调用隐式转换,而是直接调用ToString()方法,由于重写方法被注释,所以调用了默认的ValueType.ToString()方法,。
C# Console.WriteLine()与隐式类型转换的探究
本文详细解析了C#中Console.WriteLine()方法如何处理自定义类型,通过一个Currency结构体示例展示了隐式类型转换与ToString()方法的调用顺序。当存在隐式转换时,WriteLine()会首先尝试隐式转换,否则调用ToString()。而在字符串插值中,$会直接调用ToString()方法,不涉及隐式转换。理解这些规则对于编写高效且清晰的代码至关重要。
2526

被折叠的 条评论
为什么被折叠?



