简体   繁体   English

c# 新手:这段代码不像我预期的那样工作......为什么?

[英]c# newbie: this code is not working like I expected ... why?

Trying to learn more about less common constructs in C#, I ran into this code sample on codingsight.com:为了更多地了解 C# 中不太常见的构造,我在 codingsight.com 上遇到了以下代码示例:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp2
{
    class Program
    {
        static void Main(string[] args)
        {
            MyClassB b = new MyClassB();
            MyClassA a = b;
            a.abc();
            Console.ReadLine();
        }
    }

    class MyClassA
    {
        public MyClassA()
        {
            Console.WriteLine("constructor A");
        }

        public void abc()
        {
            Console.WriteLine("A");
        }
    }

    class MyClassB : MyClassA
    {
        public MyClassB()
        {
            Console.WriteLine("constructor B");
        }

        public void abc()
        {
            Console.WriteLine("B");
        }
    }
}

The challenge is to predict the output.挑战在于预测输出。 Running the code in a console there appears:在控制台中运行代码会出现:

constructor A
constructor B
A

I had bet my last cent that the 3rd line of the output would be "B", or an "unitialized variable" error, but in fact it is "A".我打赌我的最后一分钱输出的第三行将是“B”,或“统一变量”错误,但实际上它是“A”。 Why?为什么?

Why?为什么?

Because it's a concept of the .NET language called hiding through inheritance .因为它是 .NET 语言的一个概念,称为通过继承隐藏 It's defined that way and there's no reasoning given by Microsoft why it was done that way.它是这样定义的,微软没有给出为什么这样做的理由。 They could have chosen any other behavior as well, but they didn't.他们也可以选择任何其他行为,但他们没有。

In the comments you say:在评论中你说:

What the computer did is "something", but clearly not what the intention of the code was.计算机所做的是“某事”,但显然不是代码的意图。

Actually, we don't know what the intention was.实际上,我们不知道它的意图是什么。 We would need to ask the author of that code snippet.我们需要询问该代码片段的作者。 I would say it was intended the way it is, because it is a great question to see whether or not someone has understood the principles of inheritance.我会说它的目的是这样,因为看看有人是否理解继承原则是一个很好的问题。

In the title, you mention that there is a warning - and that warning is exactly a warning to the author that he didn't express his intention well enough.在标题中,你提到有一个警告——这个警告正是对作者的警告,他没有很好地表达他的意图。 Or it's a warning to you as a reader that the writer has not expressed his intention well enough.或者它是对读者的警告,作者没有很好地表达他的意图。

The warning is警告是

warning CS0108: 'MyClassB.abc()' hides inherited member 'MyClassA.abc()'.警告 CS0108:“MyClassB.abc()”隐藏继承的成员“MyClassA.abc()”。 Use the new keyword if hiding was intended.如果打算隐藏,请使用 new 关键字。

That warning also tells us that the author should have used the new keyword on MyClassB.abc() to definitely tell readers that he's using "hiding through inheritance" explicitly.该警告还告诉我们,作者应该在MyClassB.abc()上使用new关键字明确地告诉读者他正在使用“通过继承隐藏”。

Now, what's the alternative?现在,有什么替代方案? If you want to have inheritance as expected by you, MyClassA.abc() needs to be marked as virtual .如果您想按照您的预期进行继承,则需要将MyClassA.abc()标记为virtual

This change alone, hoewever, does not fix the inheritance as expected by you.然而,仅此更改并不能像您预期的那样修复继承。 There's another compiler warning还有另一个编译器警告

warning CS0114: 'MyClassB.abc()' hides inherited member 'MyClassA.abc()'.警告 CS0114:“MyClassB.abc()”隐藏继承的成员“MyClassA.abc()”。 To make the current member override that implementation, add the override keyword.要使当前成员覆盖该实现,请添加 override 关键字。 Otherwise add the new keyword.否则添加新关键字。

which clearly states that MyClassB.abc() also needs to be marked as override .其中明确指出MyClassB.abc()也需要标记为override

It seems you're most confused about the statement看来你对这句话最困惑

MyClassA a = b;

That statement is equivalent to该语句相当于

MyClassA a = (MyClassA) b;

but the cast is redundant because of implicit reference conversion :但由于隐式引用转换,演员表是多余的:

The implicit reference conversions are:隐式引用转换是:

[...] [...]

From any class_type S to any class_type T , provided S is derived from T .从任何 class_type S到任何 class_type T ,前提是S派生自T

(where S is MyClassB and T is MyClassA) (其中 S 是 MyClassB,T 是 MyClassA)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM