写这篇文章是来源于一次关于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()方法,。