Методы расширения C# - как далеко?

Rails представил некоторые базовые расширения Ruby, такие как 3.days.from_now, который возвращается, как и следовало ожидать, через три дня в будущем. С помощью методов расширения в C# теперь мы можем делать нечто подобное:

static class Extensions
{
    public static TimeSpan Days(this int i)
    {
        return new TimeSpan(i, 0, 0, 0, 0);
    }

    public static DateTime FromNow(this TimeSpan ts)
    {
        return DateTime.Now.Add(ts);
    }
}

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(
            3.Days().FromNow()
        );
    }
}

Или как насчет:

static class Extensions
{
    public static IEnumerable<int> To(this int from, int to)
    {
        return Enumerable.Range(from, to - from + 1);
    }
}

class Program
{
    static void Main(string[] args)
    {
        foreach (var i in 10.To(20))
        {
            Console.WriteLine(i);
        }
    }
}

Это в корне неверно, или бывают случаи, когда это хорошая идея, например, в таких фреймворках, как Rails?

Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
15
0
1 616
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Лично мне нравится int.To, я неоднозначно отношусь к int.Days и не люблю TimeSpan.FromNow.

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

Например, мне это плохо читается:

TimeSpan.FromSeconds(4).FromNow()

Понятно, что это субъективная вещь.

Татисматт не указал int.Days, скорее, он привел пример TimeSpan.Days. Не могли бы вы поправить, пожалуйста?

Neil Barnwell 16.12.2008 16:59

@Neil - метод расширения Days расширяет int для возврата TimeSpan.

mackenir 16.12.2008 17:21
Ответ принят как подходящий

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

Возьмем, к примеру, 3.Days().FromNow(). Это замечательно выразительно, и любой может прочитать этот код и сказать вам, что именно он делает. Это действительно прекрасная вещь. Как программисты, мы с радостью пишем код, который является самоописывающим и выразительным, так что он почти не требует комментариев и его приятно читать. В этом отношении этот код имеет первостепенное значение.

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

Методы расширения скрывают «как», чтобы лучше выразить «что». Думаю, это делает их обоюдоострым мечом, который лучше всего использовать (как и все) в умеренных количествах.

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

Robert Gowland 16.12.2008 17:16

@slowplay - Суть методов расширения в том, что они нарушают инкапсуляцию.

Sam Meldrum 12.01.2009 20:28

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

Если вы собираетесь их использовать, просто, пожалуйста, не злоупотребляйте ими до такой степени, что вы делаете их удобными для себя, но возитесь с кем-либо, кто прикоснется к вашему коду. :-)

У каждого языка есть свой собственный перспектива того, каким должен быть язык. Rails и Ruby разрабатываются со своими собственными, очень разными взглядами. У PHP явно разные мнения, как и у C (++ / #) ... как и у Visual Basic (хотя, очевидно, нам не нравится их стиль).

Весы имеют множество легко читаемых встроенных функций и тщательный контроль над всем. Я бы не хотел, чтобы у вас было так много функций, которые приходилось искать каждый раз, когда вы хотите что-то сделать (и должны быть накладные расходы на производительность из-за раздутого фреймворка), но мне лично нравится Rails, потому что то, что он имеет, меня спасает. много времени на разработку.

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

Во-первых, интуитивное ощущение: 3.Minutes.from_now выглядит совершенно круто, но не демонстрирует, почему методы расширения хороши. Это также отражает мою общую точку зрения: круто, но я никогда особо не скучал по ним.


Вопрос: 3.Minutes - это временной интервал или угол?

Пространства имен, на которые ссылается оператор using «обычно», влияют только на типы, теперь они внезапно решают, что означает 3.Minutes.

Так что лучше всего «не дать им сбежать» .
Все общедоступные методы расширения в пространстве имен, на которое, вероятно, будут ссылаться, в конечном итоге становятся «своего рода глобальными» - со всеми потенциальными проблемами, связанными с этим. Храните их внутри сборки или помещайте в отдельное пространство имен, которое добавляется к каждому файлу отдельно.

Я согласен с Siz и худым консерватором в этом вопросе. В Rails есть такие вещи, так что на самом деле это не так запутанно. Когда вы пишете методы «days» и «fromnow», нет гарантии, что ваш код не содержит ошибок. Кроме того, вы добавляете зависимость в свой код. Если вы поместите свои методы расширения в отдельный файл, вам понадобится этот файл в каждом проекте. Вы должны включать этот проект в проект всякий раз, когда он вам нужен.

Все это говорит о том, что для действительно простых методов расширения (таких как использование Джеффом "оставил" или использование thisismatt для days.fromnow выше), которые существуют в других фреймворках / мирах, я думаю, что это нормально. Любой, кто знаком с датами, должен понимать, что означает «3.Days (). FromNow ()».

Лично я предпочитаю пока использовать их экономно и подождать, чтобы увидеть, как их используют Microsoft и другие крупные организации. Если мы начнем видеть много кода, учебных пособий и книг, использующих такой код, как 3.Days (). FromNow (), он очень часто его использует. Если им будет пользоваться лишь небольшое количество людей, то вы рискуете, что ваш код будет слишком сложно поддерживать, потому что недостаточно людей знакомо с тем, как работают расширения.

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

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