C# 和方法隐藏

发布于 2024-07-27 14:19:39 字数 304 浏览 9 评论 0原文

根据 MSDN,“new”关键字在用于方法隐藏时只会抑制警告。

http://msdn.microsoft.com/en-us/library/435f1dw2。 aspx

我真的需要这个“new”关键字来执行方法隐藏吗? 如果我有一个具有相同方法名称但没有明确声明它是重写的子类,那么本质上不是同一件事吗?我只是收到警告? 请告诉我我的理解是否正确。 谢谢

Per MSDN, the "new" keyword when used for method hiding only suppresses a warning.

http://msdn.microsoft.com/en-us/library/435f1dw2.aspx

Do I really need this "new" keyword to perform method hiding? If I have a child class that has the same method name but doesn't explicitly state that it is overriding, isn't that the same thing essentially, I just get a warning? Please tell me if my understanding is correct. Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

ま柒月 2024-08-03 14:19:39

无论是否指定“new”,方法都会隐藏,但这与覆盖不同。 下面是它们不同的示例:

using System;

class Base
{
    public virtual void OverrideMe()
    {
        Console.WriteLine("Base.OverrideMe");
    }

    public virtual void HideMe()
    {
        Console.WriteLine("Base.HideMe");
    }
}

class Derived : Base
{
    public override void OverrideMe()
    {
        Console.WriteLine("Derived.OverrideMe");
    }

    public new void HideMe()
    {
        Console.WriteLine("Derived.HideMe");
    }
}

class Test
{
    static void Main()
    {
        Base x = new Derived();
        x.OverrideMe();
        x.HideMe();
    }
}

输出为:

Derived.OverrideMe
Base.HideMe

尽管基本 HideMe 方法是虚拟的,但它不会在 Derived 中被覆盖,它只是被隐藏 - 所以方法仍然绑定到Base中的虚拟方法,这就是执行的方法。

成员隐藏通常是一个坏主意,这会使代码更难理解。 事实上,它的可用在版本控制方面是有益的,但是,这意味着向基类添加方法不会让派生类无意中覆盖它,并且它们可以像以前一样继续工作。 这就是您收到警告的原因。

You get method hiding whether or not you specify "new", but it's not the same as overriding. Here's an example where they're different:

using System;

class Base
{
    public virtual void OverrideMe()
    {
        Console.WriteLine("Base.OverrideMe");
    }

    public virtual void HideMe()
    {
        Console.WriteLine("Base.HideMe");
    }
}

class Derived : Base
{
    public override void OverrideMe()
    {
        Console.WriteLine("Derived.OverrideMe");
    }

    public new void HideMe()
    {
        Console.WriteLine("Derived.HideMe");
    }
}

class Test
{
    static void Main()
    {
        Base x = new Derived();
        x.OverrideMe();
        x.HideMe();
    }
}

The output is:

Derived.OverrideMe
Base.HideMe

Even though the base HideMe method is virtual, it isn't overridden in Derived, it's just hidden - so the method is still bound to the virtual method in Base, and that's what gets executed.

Member hiding is generally a bad idea, making the code harder to understand. The fact that it's available is beneficial in terms of versioning, however - it means adding a method to a base class doesn't potentially let derived classes override it unintentionally, and they can keep working as before. That's why you get the warning.

弥枳 2024-08-03 14:19:39

隐藏(隐藏)方法时应始终使用 new 关键字。 尽管从技术上讲,它不会对功能产生影响,但正如您正确指出的那样,强烈建议这样做。

关键字的出现不仅向代码读者清楚地表明您在基类中显式隐藏了同名的方法,而且它的用法是官方 (MSDN) C# 指南的一部分,很可能是因为它将来可能需要使用。

当您省略关键字时,当前编译器仅向您发出警告(而不是错误),这纯粹是出于向后兼容性的原因。 正如 MSDN 所建议的那样,C# 1.0 不支持使用 new 关键字来隐藏类成员,并且会自动执行方法(通常是成员)隐藏。 我怀疑 MS 会尝试在这方面保持向后兼容性,但在未来的 C# 版本中肯定不能保证这一点。

The new keyword should always be used when hiding (shadowing) methods. Although technically it does not make a difference to functionality, as you correctly point out, it is strongly recommended.

The prescence of the keyword not only indicates clearly to the reader of the code that you are explicitly hiding a method of the same name in the base class, but also its usage is part of the official (MSDN) C# guidelines, quite possibly because its usage may be required in the future.

The reason that the current compiler only gives you a warning (rather than an error) when you omit the keyword is purely for reasons of backward compatibility. C# 1.0 does not support the new keyword for hiding members of classes, as MSDN suggests, and method (generally member) hiding was performed then automatically. I suspect MS will try to maintain backward compatibility in this respect, but it's certainly not guaranteed in future versions of C#.

讽刺将军 2024-08-03 14:19:39

在隐藏方法时使用 new 关键字是为了“使程序员的意图清晰”。 这可以避免程序员意外隐藏。

如果 new 关键字不存在,则编译器会发出警告并将其视为存在。

您可以阅读有关它的更多信息 使用 Override 和 New 关键字进行版本控制(C# 编程指南)

Use of new keyword while hiding a method is to "make the intent of the programmer clear". This avoids accidental hidings by the programmers.

If the new keyword is not present then the compiler issues a warning and treats it as if it was present.

You can read more about it Versioning with the Override and New Keywords (C# Programming Guide)

栖竹 2024-08-03 14:19:39

方法隐藏与重写不同。 不要在您应该选择覆盖的情况下使用它,因为它们的工作方式不同。

我前段时间写过这个,你可能想阅读 方法隐藏或覆盖 - 或 new 和 virtual 之间的区别了解更多详细信息。

不应该鼓励方法隐藏,因为它会改变类的语义。 功能会根据您是否有对基类或实际类的引用而变化。 这是编译器发出警告的主要原因。 如果调用者不知道正在使用方法隐藏,它可能会做出意想不到的事情。

附加

基于问题的更新。 方法隐藏不需要关键字 new,尽管您应该明确它并使用关键字(如果您正在这样做)。 它删除了编译器警告并提醒其他开发人员(或 6 个月后的您自己)您的意图是什么。

我仍然不建议隐藏方法,不过,

更新:2011 年 14 月 5 日

我移动了我的博客,因此我正在更新所有旧链接

Method hiding is not the same as overriding. Do not use it where overriding should be your choice as they work differently.

I wrote about this some time ago, you might want to read Method hiding or overriding - or the difference between new and virtual for more details.

Method hiding should be discouraged because it changes the semantics of a class. The functionality changes depending on if you have a reference to the base, or the actual class. That's the main reason there is a compiler warning about it. It can do unexpected things if the caller is not aware that method hiding is in use.

ADDITIONAL

Based on updates to the question. Method Hiding does not require the keyword new, although you should make it explicit and use the keyword if that is what you are doing. It removes the compiler warning and alerts other developers (or yourself 6 months down the line) what your intention was.

I still wouldn't recommend method hiding, tho'

UPDATE: 14/5/11

I moved my blog, so I'm updating any old links

若水般的淡然安静女子 2024-08-03 14:19:39

使用“new”和“不使用new”之间的唯一区别是,当您不使用“new”关键字时,您将收到编译器警告,以提醒开发人员任何无意的方法隐藏正在发生的情况。 在以下 URL,您还可以找到一个精彩的视频,解释 方法隐藏以及使用“new”和“不使用new”的区别

The only difference between using "new" and "not using new" is that, you will get a compiler warning when you don't use the "new" keyword, to alert the developer of any inadvertent method hiding that is happening. At the following URL you can also find an excellent video explaining method hiding and the difference between using "new" and "not using new".

苦行僧 2024-08-03 14:19:39

它是 C# 的一部分,就像 ref 和 out 一样。 这个想法是警告您,您的 API 正在重写一个方法,该方法可能会影响依赖于您的类的子类/超类的代码。

放置 new 关键字会迫使您思考这是否真的是您想要做的事情,就像需要 ref 或 out 一样,以便您必须考虑代码提供的合同。

It's part of C#, just like ref and out. The idea is to warn you that your API is overriding a method which could affect code that relies on sub/superclasses of your class.

Placing the new keyword forces you to think about whether that is really what you intended to do or not, just like requiring ref or out so that you have to think about the contract your code is providing.

故人爱我别走 2024-08-03 14:19:39

据我所知,唯一的区别是您建议的: new 隐藏警告。 我尝试了以下代码:

class Base
{
    public void Test(){}
}

class ChildA : Base
{
    public void Test(){}
}


class ChildB : Base
{
    public new void Test(){}
}

两个类的测试方法在 IL 中看起来相同:

.method public hidebysig instance void  Test() cil managed
{
  // Code size       1 (0x1)
  .maxstack  8
  IL_0000:  ret
} // end of method ChildA::Test

.method public hidebysig instance void  Test() cil managed
{
  // Code size       1 (0x1)
  .maxstack  8
  IL_0000:  ret
} // end of method ChildB::Test

编译器在 ClassA 中发出了针对 Test 的警告,但在 ClassB< 中则没有发出警告。 /代码>。 但正如其他答案所说; 不要混淆方法隐藏和方法重写的概念; 不是同一件事。

As far as I know, the only difference is the one you suggest: new hides the warning. I tried out the following code:

class Base
{
    public void Test(){}
}

class ChildA : Base
{
    public void Test(){}
}


class ChildB : Base
{
    public new void Test(){}
}

The test method for both classes look identical in IL:

.method public hidebysig instance void  Test() cil managed
{
  // Code size       1 (0x1)
  .maxstack  8
  IL_0000:  ret
} // end of method ChildA::Test

.method public hidebysig instance void  Test() cil managed
{
  // Code size       1 (0x1)
  .maxstack  8
  IL_0000:  ret
} // end of method ChildB::Test

The compiler issued a warning for Test in ClassA, but not in ClassB. But as other answers has stated; don't confuse the concepts of method hiding and method overriding; not the same thing.

も让我眼熟你 2024-08-03 14:19:39

new 的使用是当你想要一个同名的函数,但又不想要的时候
想要覆盖。 它打破了虚拟调度链。

当有人将函数添加到具有以下内容的基类时,可能会发生这种情况
与派生类函数的名称相同。

The use of new is when you want a function of the same name, but you don't
want to override. It breaks the virtual dispatch chain.

This might happen when somebody adds a function to a base class that has the
same name as your derived class function.

粉红×色少女 2024-08-03 14:19:39

多谢你们。 我知道隐藏和覆盖之间的区别,我只是好奇使用“new”和不使用“new”进行隐藏之间是否存在功能差异。 根据您所有的答案,似乎并非如此,尽管有人提出了一个很好的观点,因为它可以使代码更清晰,并且将来可能是必要的。 再次感谢各位!

Thanks guys. I am aware of the differences between hiding and overriding, I was just curious if there was a functionality difference between using "new" and not using "new" for hiding. According to all of your answers, it seems not although as someone had raised a good point in that it makes for cleaner code and it may be necessary in the future. THanks again Folks!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文