我有一个关于以下代码的问题:
class CurrentDate
{
static void Main()
{
Console.WriteLine(DateTime.Now);
}
}文件上说:
使用指定的格式信息将指定对象数组的文本表示形式(后面跟着当前行终止符)写入标准输出流。
所以我的问题是:为什么WriteLine知道DateTime对象的文本表示?我的意思是,如果我从自己的类中创建自己的对象,它如何知道如何将值转换为文本?更重要的是,它是如何知道价值的呢?如何定义对象的“值”?
发布于 2015-05-23 14:14:27
为什么WriteLine知道DateTime对象的文本表示?我的意思是,如果我从自己的类中创建自己的对象,它如何知道如何将值转换为文本?
Console.WriteLine有一个匹配特定类型(主要是原语)的一组过载。如果编译器不将重载与所提供的类型匹配,那么它将与使用System.Object的重载匹配(允许您提供单个参数)。如果发生这种情况,它将检查类型是否实现了IFormattable,如果实现了,则调用IFormattable.ToString(null, Formatter)。如果没有,它会调用对象上的ToString。ToString是在System.Object中定义的,所有对象都是从它继承的。每一个需要自定义表示的对象都会覆盖默认行为,就像DateTime一样。
例如,假设您有一个具有Foo字符串属性的Bar类,并且希望Console.WriteLine在将Foo传递给它时打印一些有意义的内容:
public class Foo
{
public string Bar { get; set; }
public override string ToString()
{
return Bar;
}
}现在我们想把它传递给Console.WriteLine
public static void Main(string[] args)
{
var foo = new Foo { Bar = "bar" };
Console.WriteLine(foo);
}会产生“酒吧”。
发布于 2015-05-23 14:13:49
由于Console.WriteLine(DateTime)没有重载,因此调用Console.WriteLine(Object)重载,并调用这个过载呼叫 过载,即已执行为
IFormattable f = value as IFormattable;
if (f != null)
WriteLine(f.ToString(null, FormatProvider));
else
WriteLine(value.ToString());如您所见,此方法检查此对象类型是否实现了接口。从实现此接口开始,您的f.ToString(null, FormatProvider)将被调用。从该方法的文档中,第一个参数是:
空引用( Visual中为Nothing),用于使用为实现类型定义的IFormattable默认格式。
从DateTime.ToString(String, IFormatProvider)方法的文档中:
如果格式为null或空字符串(""),则使用标准格式说明符
"G"。
这意味着,表示将是属于您的ShortDatePattern和LongTimePattern属性的组合。
如果您希望为您的自定义类提供一种特殊的格式,则可以使用您的类型的方法来更改其行为。
发布于 2015-05-23 15:17:26
与一些人所想的相反,DateTime.ToString() 不会被称为。在.NET中,对象可以有两种“串”自身的方法:重写string Object.ToString()方法和实现IFormattable接口。DateTime两者都有。
现在..。当你试着做
Console.WriteLine(DateTime.Now);选择了空public static void WriteLine(Object value)重载(如果在Visual中Ctrl+Click on WriteLine,您可以看到它)。此方法只调用TextWriter.WriteLine(value)方法,这样做:
IFormattable f = value as IFormattable;
if (f != null)
WriteLine(f.ToString(null, FormatProvider));
else
WriteLine(value.ToString());使用ILSpy可以很容易地看到所有这些,并查找Console.WriteLine。
https://stackoverflow.com/questions/30413683
复制相似问题