Методы Static и Instance с одинаковым именем? - PullRequest
51 голосов
/ 02 октября 2008

У меня есть класс со статическим и нестатическим интерфейсом в C #. Возможно ли иметь статический и нестатический метод в классе с одинаковыми именем и сигнатурой?

Я получаю ошибку компилятора, когда пытаюсь это сделать, но по какой-то причине я подумал, что есть способ сделать это. Я ошибаюсь или нет возможности использовать как статические, так и нестатические методы в одном классе?

Если это невозможно, есть ли хороший способ реализовать что-то подобное, которое можно применить в любой ситуации?

EDIT
Из полученных ответов ясно, что сделать это невозможно. Я собираюсь использовать другую систему имен для решения этой проблемы.

Ответы [ 6 ]

57 голосов
/ 02 октября 2008

Нет, ты не можешь. Причина ограничения заключается в том, что статические методы также могут вызываться из нестатического контекста без необходимости добавлять имя класса (поэтому MyStaticMethod () вместо MyClass.MyStaticMethod ()). Компилятор не может сказать, что вы ищете, если у вас есть оба.

Вы можете использовать статические и нестатические методы с одинаковыми именами, но с разными параметрами, следуя тем же правилам, что и при перегрузке методов, они просто не могут иметь одинаковую сигнатуру.

43 голосов
/ 20 февраля 2012

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

interface IFoo
{
    void Bar();
}

class Foo : IFoo
{
    static void Bar()
    {
    }

    void IFoo.Bar()
    {
        Bar();
    }
}

Иногда я сталкиваюсь с такой ситуацией, когда создаю классы-оболочки для вызовов P / Invoke.

12 голосов
/ 02 октября 2008

Вы можете вызывать статические методы из методов экземпляра без указания имени типа:

class Foo
{
    static void Bar()
    {
    }

    void Fizz()
    {
        Bar();
    }
}

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

Чего ты пытаешься достичь? Трудно предложить обходной путь, не зная специфики. Я бы просто переименовал один из методов.

3 голосов
/ 29 апреля 2017

C # плохо спроектирован, когда дело доходит до этого ...

Хотя это правда, что вы можете хотеть глобальный или неглобальный, он должен выбрать один по умолчанию, а если вы хотите другой, то вы просто уточните его больше.

class Logger {
   public static Logger instance;

   public static void Log(string message) {
       instance.Log(message); // currently the compiler thinks this is ambiguous, but really its not at all.  Clearly we want the non-static method
   }

   public void Log(string message) {

   }

   public void DoStuff() {
      Log("doing instance stuff"); // this could be ambiguous, but in my opinion it should default to a call to this.Log()
      Logger.Log("doing global stuff"); // if you want the global qualify it explicitly
   }
}
0 голосов
/ 06 июня 2013

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

Другие полноценные ОО-языки (например, Smalltalk) не допускают этого, а также просто путают с людьми, которые понимают объекты. Разделение между стороной экземпляра и классовой (или статической) стороной очень важно, и наличие языка, способствующего путанице в этих деталях, является ........ не очень хорошей идеей .... но типичным для типов, которые мы ожидаем от MS.

Адриан

0 голосов
/ 02 октября 2008

Вы можете иметь статический и экземплярный метод с одним и тем же именем, если их объявление отличается количеством или типом параметров. Это то же правило о том, как вы можете иметь два метода экземпляра с одним и тем же именем в классе.

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

Обновление : я допустил ошибку. Возвращаемых значений недостаточно, чтобы иметь другую подпись.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...