Можно ли переопределить статический метод в C#?

мне сказали, что static методы имплицитно final и поэтому не может быть переопределен. Это правда?

  1. может ли кто-нибудь дать лучший пример переопределения статического метода?

  2. Если статические методы - это просто методы класса, какова реальная польза от их наличия?

3 ответов


(1) статические методы нельзя переопределить, однако их можно скрыть с помощью ключевого слова "new". В основном переопределение методов означает, что вы ссылаетесь на базовый тип и хотите вызвать производный метод. Поскольку статические являются частью типа и не подлежат поиску 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.Бар или бар.Явно бар. Поэтому переопределение не имеет смысла здесь (try выражая это в коде...).

(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).


Ну вы не можете переопределить статический метод. Статический метод не может быть виртуальным, поскольку он не связан с экземпляром класса.

метод "overriden" в производном классе на самом деле является новым методом, не связанным с тем, который определен в базовом классе (следовательно, новое ключевое слово).

Это важно понять: когда типы наследуются от других типов, они выполняют общий контракт, тогда как статические типы не связаны никаким контрактом (из чистой точки ООП зрения). В языке нет технического способа связать два статических типа вместе с договором" наследования". Если вы" переопределите " метод Log в двух разных местах.

Если вы думаете о oveeriding статических методах, это действительно не имеет смысла; для того, чтобы иметь виртуальную отправку, вам нужен фактический экземпляр объекта для проверки.

статический метод также не может реализовать интерфейс; если этот класс реализует интерфейс IRolesService, то Я бы сказал, что метод Вообще не должен быть статичным. Лучше разработать метод экземпляра, чтобы вы могли поменять свой MockRoleService на реальный сервис, когда будете готовы


вы не переопределяете статический метод. Ты его прячешь. См.ответ для получения дополнительной информации.

некоторые причины использовать статические методы:

  1. они немного быстрее чем методы экземпляра. Также смотрите это статья msdn что дает представление чисел в (встроен статический вызов СР 0,2 НС, статический вызов СР 6.1 НС, встроен экземпляра вызова СР 1.1 НС, назвать экземпляр авг 6.8 НС)
  2. меньше подробностей write out-не нужно создавать экземпляр класса, чтобы добраться до них (и создание экземпляра также может повлиять на производительность)