32

今天,我在遗留代码中发现了一些东西。它具有一项功能的“静态新”。它看起来像这样。

class Foo
{
    public static void Do()
    {
        Console.WriteLine("Foo.Do");
    }
}

class Bar: Foo
{
    public static new void Do()
    {
        Console.WriteLine("Bar.Do");
    }
}

我不理解类Bar中Do方法的静态 new修饰符。在 C# 中,静态方法只能使用类名而不是对象名来调用。所以,我认为拥有“新”和没有“新”之间没有任何区别。

通常,如果某些语法是不必要的,C# 只是将其视为错误。有人知道为什么 C# 允许这样的语法吗?

4

4 回答 4

46

如果你从你的代码中删除新的,你会得到:

警告 CS0108:“Bar.Do()”隐藏了继承的成员“Foo.Do()”。如果打算隐藏,请使用 new 关键字。

C# 编译器只是警告您您可能正在做一些您不打算做的事情,并要求您插入关键字以确认您知道自己在做什么。除了抑制警告之外,它没有其他效果。

于 2009-03-19T06:51:05.233 回答
14

这仅适用于外部呼叫者。请记住,您可以调用基类的静态方法,所以这样的事情是有效的:

class Foo
{
    public static void Do() { Console.WriteLine("Foo.Do"); }
}
class Bar : Foo // :Foo added
{
    public static void Something()
    {
        Do();
    }
}

这就是警告告诉您放置新的原因,您希望在执行此操作时避免任何混淆:

class Foo
{
    public static void Do() { Console.WriteLine("Foo.Do"); }
}
class Bar : Foo // :Foo added
{
    public static void Something()
    {
        Do();
    }
    public static new void Do() { Console.WriteLine("Bar.Do"); }
}
于 2009-03-19T06:57:22.330 回答
8

看看这个

public class BaseC
{
    public static int x = 55;
    public static int y = 22;
}

public class DerivedC : BaseC
{
    // Hide field 'x'.
    new public static int x = 100;

    static void Main()
    {
        // Display the new value of x:
        Console.WriteLine(x);

        // Display the hidden value of x:
        Console.WriteLine(BaseC.x);

        // Display the unhidden member y:
        Console.WriteLine(y);
    }
}
/*
Output:
100
55
22
*/

为了清楚起见,您的示例应该是

public class Foo
{
    public static void Do() {}
}
public class Bar :Foo
{
    public new static void Do() {}
}
于 2009-03-19T06:43:53.830 回答
4

在您的示例中,第二个类 Bar 似乎没有从 Foo 继承。这似乎是一个错字,因为否则它没有意义。

假设它是一个错字,“new”修饰符显式隐藏了函数的基类版本Do()。这意味着该Do()方法的派生版本有效地替换了基类版本。

此处使用“new”记录了继承方法旨在替代Do().

有关详细信息,请参阅新修饰符 (C#)

于 2009-03-19T06:54:42.417 回答