在C#中可以重写静态方法吗
本文关键字:重写 静态方法 | 更新日期: 2023-09-27 17:58:42
我被告知static
方法是隐式final
,因此不能重写。这是真的吗?
-
有人能给出一个更好的重写静态方法的例子吗?
-
如果静态方法只是类方法,那么拥有它们的真正用途是什么?
(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模式中用于获取一个类型的单个实例。另一个例子是"static void Main",它是程序中的主要访问点。
基本上,只要你不想或在使用对象实例之前无法创建对象实例,就可以使用它们。例如,当静态方法创建对象时。
[更新]
一个简单的隐藏示例:
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
,则无法执行此操作。静态类必须从object
派生。
这与继承的主要区别在于,编译器可以在编译时确定使用静态时调用哪个方法。如果您有对象的实例,则需要在运行时执行此操作(称为vtable查找)。
你不能重写静态方法。静态方法不能是虚拟的,因为它与类的实例无关。
派生类中的"overrided"方法实际上是一个新方法,与基类中定义的方法无关(因此使用了new关键字)。
这是一件需要理解的重要事情:当类型从其他类型继承时,它们实现了一个公共契约,而静态类型不受任何契约的约束(从纯粹的OOP角度来看)。在该语言中,没有任何技术方法可以将两个静态类型与"继承"约定联系在一起。如果要在两个不同的位置"覆盖"Log方法。
如果你考虑重写静态方法it,那就没有意义了;为了进行虚拟调度,您需要检查对象的实际实例。
静态方法也不能实现接口;如果这个类实现了一个IRolesService接口,那么我认为这个方法根本不应该是静态的。最好设计一个实例方法,这样当您准备好
您不会覆盖静态方法。您将其隐藏。有关详细信息,请参阅此答案。
使用静态方法的一些原因:
- 它们比实例方法快一点。另请参阅这篇msdn文章,它给出了支持这一点的性能数字(内联静态调用平均值0.2 ns,静态调用平均数6.1 ns,内联实例调用平均值1.1 ns,实例调用平均数6.8 ns)
- 写起来不那么冗长-不需要实例化一个类就可以访问它们(实例化也会影响性能)