静态方法可以在C#中重写吗?

静态方法可以在C#中重写吗?,c#,overriding,static-methods,final,C#,Overriding,Static Methods,Final,我被告知静态方法是隐式的最终,因此不能被重写。这是真的吗 有人能给出一个更好的重写静态方法的例子吗 如果静态方法只是类方法,那么拥有它们的真正用途是什么 不能重写静态方法。你把它藏起来。有关更多信息,请参阅 使用静态方法的一些原因: 它们是多个方法的实例。另请参见此图,其中给出了支持此功能的性能数字(内联静态调用平均值0.2 ns,静态调用平均值6.1 ns,内联实例调用平均值1.1 ns,实例调用平均值6.8 ns) 写出来的话就不那么冗长了——不需要实例化类来访问它们(实例化也会影响性能)

我被告知
静态
方法是隐式的
最终
,因此不能被重写。这是真的吗

  • 有人能给出一个更好的重写静态方法的例子吗

  • 如果静态方法只是类方法,那么拥有它们的真正用途是什么


  • 不能重写静态方法。你把它藏起来。有关更多信息,请参阅

    使用静态方法的一些原因:

  • 它们是多个方法的实例。另请参见此图,其中给出了支持此功能的性能数字(内联静态调用平均值0.2 ns,静态调用平均值6.1 ns,内联实例调用平均值1.1 ns,实例调用平均值6.8 ns)
  • 写出来的话就不那么冗长了——不需要实例化类来访问它们(实例化也会影响性能)

  • 你不能重写一个静态方法。静态方法不能是虚拟的,因为它与类的实例无关

    派生类中的“overrided”方法实际上是一个新方法,与基类中定义的方法无关(因此是new关键字)

    理解这一点很重要:当类型从其他类型继承时,它们实现了一个公共契约,而静态类型不受任何契约的约束(从纯OOP的角度来看)。该语言中没有技术方法将两个静态类型与“继承”契约绑定在一起。如果要在两个不同的位置“重写”Log方法

    如果你想覆盖它的静态方法,那就没有什么意义了;为了进行虚拟分派,您需要检查对象的实际实例

    静态方法也不能实现接口;如果这个类正在实现一个IRolesService接口,那么我认为这个方法不应该是静态的。更好的设计是使用实例方法,这样当您准备就绪时,您可以将MockRoleService替换为实际服务。(1)静态方法不能被覆盖,但是可以使用“new”关键字隐藏它们。大多数重写方法意味着引用基类型并希望调用派生方法。因为static是类型的一部分,并且不受vtable查找的影响,这是没有意义的

    例如,静力学不能做:

    public class Foo { 
        public virtual void Bar() { ... }
    }
    public class Bar : Foo {
        public override void Bar() { ... }
    }
    
    // use:
    Foo foo = new Bar(); // make an instance
    foo.Bar(); // calls Bar::Bar
    
    因为静态不适用于实例,所以您总是显式地指定Foo.Bar或Bar.Bar。所以重写在这里没有意义(试着用代码表达它…)

    (2) 静态方法有不同的用法。例如,在Singleton模式中使用它来获取类型的单个实例。另一个例子是“staticvoidmain”,它是程序中的主要访问点

    基本上,只要不想或无法在使用对象实例之前创建对象实例,就可以使用它们。例如,当静态方法创建对象时

    [更新]

    一个简单的隐藏示例:

    public class StaticTest
    {
        public static void Foo() { Console.WriteLine("Foo 1"); }
        public static void Bar() { Console.WriteLine("Bar 1"); }
    }
    
    public class StaticTest2 : StaticTest
    {
        public new static void Foo() { Console.WriteLine("Foo 2"); }
        public static void Some() { Foo(); Bar(); } // Will print Foo 2, Bar 1
    }
    
    public class TestStatic
    {
        static void Main(string[] args)
        {
            StaticTest2.Foo();
            StaticTest2.Some();
            StaticTest.Foo();
            Console.ReadLine();
        }
    }
    
    请注意,如果将类设置为静态的,则不能执行此操作。静态类必须从
    对象
    派生


    这与继承之间的主要区别在于,编译器可以在编译时确定在使用static时调用哪个方法。如果您有对象实例,则需要在运行时执行此操作(称为vtable查找)。

    否,它们不能被覆盖。它们与类关联,而不是与对象关联。真正的用途是:您可以在不使用类实例的情况下调用静态方法。谢谢。我明白,最好的例子是SLaks。因此,对于我关于重写静态方法的问题(如果默认情况下是final,而不是user make it final),这是否意味着这个类中持有静态的子类不能定义具有相同签名的静态方法?顺便说一句,这似乎是我的试卷中提出的一个问题:PI不认为你是我的同班同学:D,但很高兴。PS:如果注意到我问题的新手味道,是的,我正处于学习正确理论的阶段——我意识到没有它们,我只能编写算法代码,但无法正确解释:)我对实例方法没有问题。我了解到,
    静态
    类不能被实例化。但您提到“静态方法是指它在应用程序中只实例化一次”。。所以我现在很困惑。你是指
    使用System.Math通过说静态方法是实例化的?我已经在同一个类中多次使用Math类成员Math.Abs(),甚至一次都没有实例化它们。1) 那么,你能澄清一下“实例化一次”是什么意思吗?2) 静态类可以是子类吗?将静态类划分为子类有意义吗?请参见我的编辑。我不应该在静态方法中使用术语“实例化”。更正确的说法是,它只创建一次。所有方法都只“创建”一次。即使是非静态方法也只有一个代码副本(IL代码在编译时创建,在运行时转换为机器代码一次)。不要混淆代码和数据!非静态方法只能通过对象实例调用,但这是因为传递给它的隐藏“this”指针。代码本身是“静态的”,因为它是固定的和单例的。@MatthewWatson感谢您的更正。我删除了冒犯性的部分并更新了答案我的问题是一个糟糕的问题,我得到了否决票:(?人们在否决票时会说为什么吗?NVM,更重要的是,我在这里得到了很好的答案。)@MatthewWatson谢谢,这是一个很好的问题。谢谢。这对我来说有点难理解,但一路上我会明白:)附言:如果是这样的话,我肯定想上你们班。发现他很好,即使我也在学习c#…我22岁,在公司工作..经历简单的事情你会一步一步地得到它。谢谢你给我这个超越的例子。是的,我正在代码中尝试。所以为了得到正确的结果,1)我们可以像任何其他非静态类一样对静态类进行子类划分?2) 我们可以使用静态方法,而不重写父类静态方法,而是使用