Одноименные статические методы и методы экземпляра?

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

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

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

РЕДАКТИРОВАТЬ
Из полученных мной ответов ясно, что это невозможно сделать. Я собираюсь использовать другую систему именования, чтобы обойти эту проблему.

Можете ли вы привести пример того, где вы могли бы это сделать?

Eric Schoonover 02.10.2008 02:56

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

Euro Micelli 02.10.2008 05:49

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

Scott Dorman 02.10.2008 18:21

Этот код будет компилироваться только на C#. Моя компания использует исключительно C#, и нет никаких шансов, что код когда-либо будет преобразован или использован на другом языке, поэтому в этом случае я в безопасности.

Dan Herbert 02.10.2008 18:50

Знание разницы между Ball и BaII, или LOOP против L00P - это одно, и уже вызывает достаточно проблем, поскольку знание разницы между doSomething и DoSomething делает его действительно сложным, и, прежде чем вы это узнаете, вы обнаруживаете, что комментируете каждый случай, чтобы прояснить его для другие программисты или себя, когда вы снова посмотрите на это на следующей неделе.

Abel 05.11.2009 19:46

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

yoyo 17.08.2013 00:28
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
62
6
26 924
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

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

class Foo
{
    static void Bar()
    {
    }

    void Fizz()
    {
        Bar();
    }
}

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

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

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

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

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

Неправильно: если они различаются по количеству и / или типу параметров. Типы возврата не перегружают.

asterite 02.10.2008 02:55
Ответ принят как подходящий

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

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

Я считаю логику этого ответа ошибочной. Я не вижу причин, по которым C# не может устранять неоднозначность, требуя "this". токен для вызова метода экземпляра в этой ситуации. Кроме того, andasa показывает, как статические методы и методы экземпляра могут иметь одно и то же имя.

mheyman 27.01.2014 17:30

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

ckramer 05.02.2014 00:05

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

Nick Sotiros 29.04.2017 18:08

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

interface IFoo
{
    void Bar();
}

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

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

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

Моей точной причиной для этого были вызовы P / Invoke. Спасибо :)

Asheh 12.08.2014 20:33

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

Palec 25.03.2017 02:59

Я получаю сообщение об ошибке: Member 'Foo.Bar()' cannot be accessed with an instance reference; qualify it with a type name instead. при выполнении (new Foo()).Bar(); в моем приложении.

T.Todua 26.07.2019 14:54

@ T.Todua Да, для этого вам нужно называть его IFoo. Можно сделать либо ((IFoo)(new Foo())).Bar();, либо IFoo foo = new Foo(); foo.Bar();

Richard 04.02.2020 09:44

В ПОРЯДКЕ. Корень этой проблемы в том, что C# не должен позволять вам вызывать статический метод из метода экземпляра без указания имени типа.

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

Адриан

Ваш пост не отвечает на вопрос. Пожалуйста, подумайте о том, чтобы добавить конкретный ответ на вопрос или добавить комментарий для объяснения вопроса.

Seeta Somagani 06.06.2013 04:07

Я понимаю отрицательные голоса, потому что это не отвечает на вопрос, но это действительно причина проблемы. Для разработчика имеет смысл видеть имя класса перед статическим методом в качестве индикатора первого взгляда: «Да, это статический метод, свойство, поле» и т. д.

Brandon 13.03.2015 18:50

Три года спустя, но я хочу сказать, что ценю замечания, высказанные @Adrian, а не пару уничижительных заявлений, которые были совершенно неуместными, в частности: «C# не должен позволять вам звонить», «но типичен для того, что мы ожидаем. от MS. " Первый пункт - это ТОЧНОЕ мнение, которое следует придерживаться, но, по сути, его не следует высказывать.

Nicholas Petersen 02.08.2016 21:24

Горе тем, кто хочет практиковать достойную объектную архитектуру и дизайн на C#. Небольшие ограничения, подобные этому, добавляют сложности и уменьшают ясность. Класс отличается от экземпляра, и оба должны иметь возможность без путаницы объявлять «Foo». Чрезмерное удобство возможности указать Foo вместо Klass.Foo в методе экземпляра FAR подавлено многословием самого языка. Неправильная оптимизация языка - часть печальной истории происхождения C++.

The Software Barbarian 07.10.2016 21:28

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
   }
}

Другие вопросы по теме