Классифицировать собственные методы расширения

#c# #extension-methods

#c# #методы расширения

Вопрос:

Я хотел бы знать, возможно ли «классифицировать» мои методы расширения.

Я создал расширения, которые поступают из мира SQL (СЛЕВА / СПРАВА / ОБЪЕДИНЯЮТСЯ / (НЕ) В / (НЕ) МЕЖДУ / …) и хотел бы расширить его в подметоде «SQL» и использовать его следующим образом :

 "abc".SQL().Left(2);
  

или я должен создать статический класс, который ссылается на эти методы?

Спасибо за любой совет и подскажите мне наилучшую практику в этом случае.

Комментарии:

1. Итак, вам нужны вложенные методы расширения? В этом действительно отсутствует весь смысл метода расширения…

2. Вы не можете расширить метод, вы можете расширить только тип (возвращаемый тип метода). Если SQL() возвращает ваш собственный пользовательский тип, почему бы просто не добавить эти методы непосредственно к типу?

3. @Chris : Просто чтобы знать, что эти методы используют правила SQL… Но, возможно, это плохая практика 😉

4. Я не совсем понимаю вашу проблему. Похоже, что SQL это метод расширения String ? Теперь вы хотите расширить тип, который SQL возвращает, чтобы добавить Left(Integer) какой тип возвращается SQL методом расширения? Вот куда должны пойти ваши новые методы, если вы не можете изменить этот тип, тогда вам нужно расширить его тем же способом, который вы сделали String .

5. @Chris : Смотрите ответ Кристофферса. Я хотел бы создать плавный интерфейс, но вы правы, это SQL, который должен быть расширен 😉

Ответ №1:

Это то, что люди называют свободным интерфейсом. На самом деле только метод SQL () должен быть методом расширения (в классе string). Затем метод SQL может возвращать класс, в котором есть такие методы, как Left() и Coalesce(). Если вы хотите сделать это расширяемым, вы можете расширить класс / интерфейс, который возвращает ваш метод SQL.

Все методы (Left, Coalesce и т.д.) Могут возвращать один и тот же класс / интерфейс, чтобы получить поток свободного интерфейса, такого как

 string b = "abc".SQL().Left(2).Right(1).ToString();
  

Ответ №2:

Вы могли бы создать SQL() как метод entension, который возвращает класс, содержащий ваши расширения (как обычные методы), которые возвращают этот новый класс. Класс должен был бы иметь свойство / поле, которое было вашим исходным объектом, вызвавшим SQL() метод.

РЕДАКТИРОВАТЬ: Благодаря @Kristoffer я теперь знаю, что это называется fluent interface ; где API разработан для обеспечения более читаемого кода.

Ответ №3:

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

Сначала создайте класс типа ‘builder’, который обрабатывает строку, используя ваши методы Sql

  class SqlMethods
 {
      string _target; // probably want to use a StringBuilder instead

      public SqlMethods(string target)
      {
          _target = target;
      }

      SqlMethods Left(int n)
      {
          _target = ...; // implementation of Left()
          return this;
      } 

      public override string ToString() {return _target;}
 }
  

Создайте экземпляр этого класса с помощью метода расширения, подобного этому:

 static class StringExtensions
{
     public static SqlMethods SQL(this string s) {return new SqlMethods(s);}
}
  

Это позволяет использовать API, подобный этому:

 "abc".SQL().Left(2).ToString()