.NET Console.WriteLine方法ToString行为

问题描述 投票:1回答:3

据我所知.NET Console.WriteLine方法调用类的ToString方法。在下面的代码Console.WriteLine(对象)呼叫和Console.WriteLine(object.ToString())调用产生不同的输出。如果override关键字被加到ToString方法在下面的代码的输出成为相同。但我不知道为什么输出是在第一种情况不同。

程序的输出:

TestOverrideConsole.Program(类名称)

你好从程序

class Program
{
    static void Main(string[] args)
    {
        Program p = new Program();
        Console.WriteLine(p);
        Console.WriteLine(p.ToString());

        Console.ReadLine();
    }

    public String ToString()
    {
        return "Hello from Program";
    }
}
.net tostring
3个回答
0
投票

当你重写一个方法,你基本上把一个新的实现为一个已经被你的基类指定为该方法的“插槽” 1。当你影子的方法(不使用替代),你正在做的是使用你的基类的名称,并指定该名称不同的“槽”。

当编译器执行名称/重载解析,它基本上是试图决定是“插槽”借道方法调用(因为因超载,你可能有多个方法具有相同的名字,但他们将有不同的“槽“S)。

Console.WriteLine被编译,编译器可以挑选ToString唯一的插槽是Object宣布其ToString方法之一。所以这是它会永远CALL2的唯一方法。


1I'm使用“插槽”这里是因为,虽然你不会发现它在C#规格使用,只要我还记得,下跌在CLR水平,阴影方法都标有newslot

2不100%肯定它字面上叫ToString本身,而不是通过任何数量的间接性的去,但它不够好这里要说的是它。


0
投票

Console.WriteLine(p)调用ToString对象的方法ToString方法没有重写。

public String ToString()

此方法隐藏ToString基类的方法,并且不将其覆盖。这就是为什么输出不同的原因。要正确地覆盖ToString方法,你必须override关键字添加到方法声明。


0
投票

我已经修改了代码,以便对其进行编译,您可以inspect it here

using System;

public static class Program
{
    static void Main(string[] args)
    {
        var p = new P();
        Console.WriteLine(p);
        Console.WriteLine(p.ToString());
    }
}

class P
{
    public String ToString()
    {
        return "Hello from Program";
    }
}

你会看到,编译器会发出这样的警告

警告CS0114: 'P.ToString()' 揣继承的成员 'object.ToString()'。为了使当前成员重写该实现,加上override关键字。否则,添加新的关键字。

我认为这是非常自我解释。

WriteLine()调用ToString()它访问虚拟会员,你还没有覆盖。

© www.soinside.com 2019 - 2024. All rights reserved.