C#中阴影和覆盖的区别?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/392721/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 01:45:03  来源:igfitidea点击:

Difference between shadowing and overriding in C#?

c#

提问by Jox

What's difference between shadowingand overridinga method in C#?

在 C# 中隐藏覆盖方法有什么区别?

采纳答案by Stormenet

Well inheritance...

那么继承...

suppose you have this classes:

假设你有这样的课程:

class A {
   public int Foo(){ return 5;}
   public virtual int Bar(){return 5;}
}
class B : A{
   public new int Foo() { return 1;}     //shadow
   public override int Bar() {return 1;} //override
}

then when you call this:

那么当你调用这个时:

A clA = new A();
B clB = new B();

Console.WriteLine(clA.Foo()); // output 5
Console.WriteLine(clA.Bar()); // output 5
Console.WriteLine(clB.Foo()); // output 1
Console.WriteLine(clB.Bar()); // output 1

//now let's cast B to an A class
Console.WriteLine(((A)clB).Foo()); // output 5 <<<-- shadow
Console.WriteLine(((A)clB).Bar()); // output 1

Suppose you have a base class and you use the base class in all your code instead of the inherited classes, and you use shadow, it will return the values the base class returns instead of following the inheritance tree of the real type of the object.

假设您有一个基类,并且您在所有代码中使用基类而不是继承的类,并且您使用影子,它将返回基类返回的值,而不是遵循对象的真实类型的继承树。

Run code here

在这里运行代码

Hope I'm making sense :)

希望我是有道理的:)

回答by Matthew Flaschen

I think the main difference is that with shadowing, you're essentially reusing the name, and just ignoring the superclass use. With overriding, you're changing the implementation, but not the accessibility and signature (e.g. parameter types and return). See http://www.geekinterview.com/question_details/19331.

我认为主要的区别在于,使用阴影,您实际上是在重用名称,而忽略了超类的使用。通过覆盖,您正在更改实现,而不是可访问性和签名(例如参数类型和返回值)。请参阅http://www.geekinterview.com/question_details/19331

回答by AnthonyWJones

Shadowing is actually VB parlance for what we would refer to as hiding in C#.

阴影实际上是我们在 C# 中称为隐藏的 VB 用语。

Often hiding (shadowing in VB) and overriding are shown as in answer by Stormenet.

通常隐藏(VB 中的阴影)和覆盖显示为Stormenet 的回答。

A virtual method is shown to be overridden by a sub-class and calls to that method even on the super-class type or from inside code of the super-class will call the replacement implementation from the sub-class.

虚拟方法显示为被子类覆盖,并且即使在超类类型上或从超类的内部代码调用该方法也会从子类调用替换实现。

Then a concrete method is shown (one not marked as virtual or abstract) being hidden by using the newkeyword when defining a method with an identical signature on the sub-class. In this case when the method is called on the super-class type the original implementation is used, the new implementation is only available on the sub-class.

然后new在子类上定义具有相同签名的方法时,使用关键字隐藏一个具体方法(未标记为虚拟或抽象的)。在这种情况下,当在使用原始实现的超类类型上调用方法时,新实现仅在子类上可用。

However what is often missed is that it is also possible to hide a virtual method.

然而,经常被忽略的是,也可以隐藏虚拟方法。

class A
{
    public virtual void DoStuff() { // original implementation }
}

class B : A
{
    public new void DoStuff() {  //new implementation }
}

B b = new B();
A a = b;

b.DoStuff(); //calls new implementation
a.DoStuff(); //calls original implementation.

Note in the above example DoStuff becomes concrete and can not be overriden. However it is also possible to use both the virtualand newkeywords together.

注意在上面的例子中 DoStuff 变得具体并且不能被覆盖。但是,也可以同时使用 thevirtualnew关键字。

class A
{
    public virtual void DoStuff() { // original implementation }
}

class B : A
{
    public new virtual void DoStuff() {  //new implementation }
}

class C : B
{
    public override void DoStuff() { //replacement implementation }
}

C c = new C();
B b = c;
A a = b;

c.DoStuff(); //calls replacement implementation
b.DoStuff(); //calls replacement implementation
a.DoStuff(); //calls original implementation.

Note that despite all the methods involved being virtual, the override on C does not affect the virtual method on A because of the use of newin B hides the A implementation.

请注意,尽管所涉及的所有方法都是虚拟的,但 C 上的覆盖不会影响 A 上的虚拟方法,因为newB中的使用隐藏了 A 实现。

Edit:Its been noted in the comments to this answer that the above may be dangerous or at least not particularly useful. I would say yes it can be dangerous and would be out there if it were at all useful.

编辑:在对此答案的评论中指出,上述内容可能是危险的,或者至少不是特别有用。我会说是的,它可能很危险,如果它有用的话,我会在那里。

In particular you could get into all sorts of trouble if you also change the accessability modifiers. For example:-

特别是如果您还更改可访问性修饰符,您可能会遇到各种麻烦。例如:-

public class Foo
{
    internal Foo() { }
    protected virtual string Thing() { return "foo"; }
}

public class Bar : Foo
{
 internal new string Thing() { return "bar"; }
}

To an external inheritor of Bar, Foo's implementation of Thing() remains accesible and overridable. All legal and explainable according to .NET type rules neverless quite unintuative.

对于 的外部继承者BarFooThing() 的实现仍然是可访问和可覆盖的。根据 .NET 类型规则,所有合法且可解释的内容都非常不直观。

I've posted this answer to deepen an understanding of how things work not as a suggestion of techniques that can be used freely.

我发布了这个答案是为了加深对事物如何运作的理解,而不是作为可以自由使用的技术的建议。

回答by Daniel Sandeep

Basically if you have something like below,

基本上,如果您有以下内容,

Class A
{
}

Class B:A
{
}

A a = new B();

Any method you call on the object 'a' will be made on the type of 'a'(Here the type is 'A') But if you implement the same method in class B that is already present in Class A, the compiler will give you a warning to use a "New" keyword. If you use "New", the warning will disappear. Other than this there is no difference between using "New" or not using it in the inherited class.

您在对象 'a' 上调用的任何方法都将在 'a' 的类型上创建(这里的类型是 'A')但是如果您在类 B 中实现与类 A 中已经存在的相同的方法,编译器将警告您使用“New”关键字。如果您使用“新建”,警告将消失。除此之外,在继承的类中使用“New”或不使用它没有区别。

In some situations you may need to call a method of the reference class the particular instance holds at that moment instead of calling a method on the object type. In the above case the reference it holds is 'B', but the type is 'A'. So if you want the method call should happen on 'B', then you use Virtual and override to achieve this.

在某些情况下,您可能需要调用特定实例当时持有的引用类的方法,而不是调用对象类型上的方法。在上述情况下,它持有的引用是“B”,但类型是“A”。因此,如果您希望方法调用发生在“B”上,那么您可以使用 Virtual 和 override 来实现这一点。

Hope this helps...

希望这可以帮助...

Daniel Sandeep.

丹尼尔·桑迪普。

回答by Shezi

Shadowing is a VB.NET concept. In C#, Shadowing is known as Hiding. It hides the derived class method. It is accomplished using the ‘new' keyword.

阴影是 VB.NET 的概念。在 C# 中,阴影被称为隐藏。它隐藏了派生类方法。它是使用“new”关键字完成的。

Override keyword is used to provide a completely new implementation of a base class method (which is marked ‘Virtual') in the derived class.

Override 关键字用于在派生类中提供基类方法(标记为“Virtual”)的全新实现。

回答by snr

If there is a case in which you cannot alter the contents of a class, let's say A, but you want to use its some methods along with you have a method which name is common, you can use your own method implementation by the newkeyword.

如果您无法更改类的内容,例如A,但是您想使用它的某些方法以及名称通用的方法,则可以通过new关键字使用自己的方法实现。

The crux point is to use it that both the reference and object must be of the same type.

关键是使用它,引用和对象必须是相同的类型。

class A
{
    public void Test()
    {
        Console.WriteLine("base");
    }
}

class B : A
{
    public new void Test()
    {
        Console.WriteLine("sub");
    }

    public static void Main(string[] args)
    {
        A a = new A();
        B aa = new B();
        a.Test();
        aa.Test();
    }
}