Статические методы расширения

Есть ли способ добавить к классу метод статического расширения.

в частности, я хочу перегрузить Boolean.Parse, чтобы разрешить int аргумент.


person Midhat    schedule 15.05.2009    source источник
comment
Не похоже, что ты сможешь. См. здесь для обсуждения it Я бы очень хотел, чтобы меня доказали, что я ошибаюсь.   -  person Ray    schedule 15.05.2009
comment
как это может быть дубликат? Он хочет добавить метод расширения, который ведет себя как статический метод (класс), к классу, который может иметь экземпляры, такие как Boolean, тогда как другой вопрос спрашивает, как добавить метод расширения к статическому классу   -  person George Birbilis    schedule 29.11.2015
comment
было бы хорошо, если бы C # поддерживал синтаксис вроде: public static DependencyProperty Register (static DependencyProperty x, string name, Type propertyType, Type ownerType, FrameworkPropertyMetadata typeMetadata), чтобы я мог использовать его в Silverlight для достижения совместимости с синтаксисом WPF (чтобы обернуть Dr .WPF реализация принуждения значений для DependencyProperty). Обратите внимание на статический параметр DependencyProperty вместо этого DependencyProperty (в качестве альтернативы вместо static, возможно, они могли бы использовать другое ключевое слово, например type или typeof)   -  person George Birbilis    schedule 29.11.2015
comment
Та же проблема с Enum.Parse с предоставлением строки. К сожалению, расширение строки не так очевидно, как расширение int. В C # отсутствует синтаксис!   -  person C4d    schedule 18.08.2016
comment
Я думаю, что это будет возможно с помощью Shapes в будущей спецификации C #.   -  person Sinaesthetic    schedule 16.09.2018
comment
Вот запрос функции. Пожалуйста, проголосуйте за это.   -  person Kiruahxh    schedule 25.02.2021


Ответы (3)


Короче нет, нельзя.

Длинный ответ, методы расширения - это просто синтаксический сахар. IE:

Если у вас есть метод расширения для строки, скажем:

public static string SomeStringExtension(this string s)
{
   //whatever..
}

Когда вы потом назовете это:

myString.SomeStringExtension();

Компилятор просто превращает это в:

ExtensionClass.SomeStringExtension(myString);

Как видите, для статических методов это невозможно.

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

Bool.Parse(..)

vs.

Helper.ParseBool(..);

На самом деле ничего не значит ...

person BFree    schedule 15.05.2009
comment
какой смысл добавлять статические методы к существующим классам? Я хотел делать это неоднократно во многих случаях. Мое рассуждение: я хочу расширить String.Reconvert как метод расширения. Я мог бы написать Helper.ReconvertString, но, используя Visual Studio и автозаполнение, мои коллеги не смотрели бы под Helper. Они будут искать String метод и, не найдя его, скорее всего, пойдут и заново изобретут колесо. - person abelenky; 30.10.2013
comment
Я полностью не согласен, выгода от этого будет такая же, как у инстансовых методов расширения. Я мог бы также использовать вспомогательные классы для той же цели, что и обычные методы расширения, но зачем мне это делать, если подход расширения намного более элегантен для работы. Синтаксический сахар полезен, будь то экземпляр или статический. - person WiredWiz; 07.11.2013
comment
Я думаю, что они принесут столько же, сколько и синтаксический сахар. Речь идет о доступности и о том, чтобы вещи были там, где вы ожидаете, что они будут в популярных классах, а не в малоизвестных помощниках. Например, будет полезен метод расширения, такой как DateTime.FromNanoseconds, или DateTime.FromSecondsSinceEpoch. Они не имеют смысла как метод экземпляра, поскольку по сути являются конструкторами, но их легко найти как статические методы расширения. Причина в том, что классы фреймворка просто неполные, а методы расширения - обходной путь для их завершения. - person Triynko; 26.11.2013
comment
@Трийнко прав. В приведенном выше примере где и что такое класс Helper? Как узнать, где его найти и в каком пространстве имен он находится? По этим причинам расширения, которые появляются там, где вы ожидаете, являются полезной функцией. - person mungflesh; 13.08.2014
comment
Есть причина, по которой у вас есть метод string.Join вместо отдельного класса StringHelpers во фреймворке. Тем не менее, я ненавижу, когда я ожидаю метод расширения и мне приходится искать подходящее пространство имен для добавления. По крайней мере, с классами я могу щелкнуть правой кнопкой мыши и решить добавить using. - person Jason Goemaat; 03.03.2015
comment
Я думаю, что этот ответ можно было бы просто отредактировать до «Нет», поскольку это всего лишь вопрос языкового дизайна. В остальной части ответа нет ничего, что указывало бы на какие-либо конфликты при реализации статических методов расширения на языке. - person Alex; 05.09.2015
comment
Например, прямо сейчас я пишу вспомогательные методы для консоли, чтобы упростить вывод цветов и изменение положения курсора, чтобы я мог легко делать такие вещи, как живые обновления, без написания дополнительных строк, и выводить что-то в определенном цвете, не получая текущий цвет / настройку новый цвет / вывод записи / возврат к исходному цвету. Было бы неплохо добавить их в консоль, но я, вероятно, повторно реализую Write и WriteLine в своем классе, чтобы один и тот же класс можно было использовать для всего вывода. - person Jason Goemaat; 05.12.2015
comment
Я могу придумать хороший пример, в котором вам нужны статические методы расширения. Даже класс Int32 предоставляет Parse(String), Parse(String, IFormatProvider), Parse(String, NumberStyles), Parse(String, NumberStyles, IFormatProvider) перегрузки, но класс Boolean предоставляет только Parse(String). Разве не было бы замечательно иметь хотя бы Bool.Parse(String, IFormatProvider) перегрузку, чтобы можно было переводить истинные / ложные значения с других языков? например Cierto / Falso (испанский), Vrai / Faux (французский) и Правда / Ложь (русский)? - person AlwaysLearning; 13.01.2016
comment
Я не против статических расширений, но одна из причин, по которой вы, возможно, не захотите расширять общий класс CLR, заключается в том, что хотя он упрощает поиск расширения, он может предположить разработчику, что расширение на самом деле является частью исходного класса. Разработчик может попытаться использовать расширение в другом проекте, но не сможет найти его. Возможно, качели и карусели. - person tjmoore; 19.04.2016
comment
StringExtensions.Reconvert(...) - бац, проблема решена осмысленным образом, который читается, недвусмысленно, разумно и хорошо работает с IntelliSense. Это также позволяет вам размещать как методы расширения экземпляра, так и методы статического расширения как таковые в одном классе. - person John Weisz; 09.06.2016
comment
@JohnWhite Очевидно, вы не читали верхние комментарии под этим вопросом :) - person Episodex; 17.08.2016
comment
@Episodex Я сделал это, поэтому я предлагаю значимую стандартизацию для всех проектов. Просто включите в спецификации / рекомендации, что классы статических методов расширения всегда имеют форму *Extensions. Это также намного проще, чем Helpers, поскольку его можно рассматривать как совершенно другой подход - когда вы ищете статический метод на String, вы начнете с ввода Str..., после чего статический класс StringExtensions уже должен быть в списке предлагаемых слов для автозаполнения, его название четко указывает на его намерение. - person John Weisz; 17.08.2016
comment
@JohnWhite Хорошо, теперь я понимаю твои доводы. В самом деле, это, вероятно, лучшее решение до тех пор, пока (когда-либо?) Статические расширения не будут реализованы в C #. - person Episodex; 18.08.2016
comment
Методы расширения требуют, чтобы параметр this не был нулевым. Способом решения этой проблемы было бы написать статический метод, который мог бы иметь любой или все параметры равные нулю, не вызывая исключения. У меня нет исходного кода HashSet ‹T›, поэтому я не могу исправить этот недостаток UnionWith (). Если бы я мог это исправить, я бы хотел написать метод статического расширения. Поскольку это невозможно, теперь мне нужно написать локальный частный метод и поместить его в суть. - person philologon; 03.11.2017

в частности, я хочу перегрузить Boolean.Parse, чтобы разрешить аргумент int.

Будет ли работать расширение для int?

public static bool ToBoolean(this int source){
    // do it
    // return it
}

Тогда вы можете назвать это так:

int x = 1;

bool y = x.ToBoolean();
person bsneeze    schedule 15.05.2009
comment
+1 за творчество. Вы не ответили на его вопрос, но я считаю, что вы нашли наиболее элегантное решение. Особенно учитывая, что буквально анализировать означает анализировать строку :) (см. определение < / а>) - person tsemer; 18.09.2012
comment
Не забывайте, что int - это тип значения. Вам необходимо использовать его, как написал @bsneeze y=x.ToBoolean(), потому что в методах расширения для типов значений значения НЕ передаются по ссылке. - person LuckyLikey; 10.06.2015

Нет, но у вас может быть что-то вроде:

bool b;
b = b.YourExtensionMethod();
person BobbyShaftoe    schedule 15.05.2009