C#: Возврат 'этого' для вложения метода?

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

dynamic item = comboBox1.SelectedItem;
var id = (int)item.Id;
var name = (string)item.Name;
14
задан Samuel 23 April 2009 в 13:30
поделиться

8 ответов

The 'return this' style is sometimes called a fluent interface and is a common practice.

19
ответ дан 1 December 2019 в 10:04
поделиться

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

Еще одна идея сделать интерфейс, подобный сумматорам, более простым в использовании:

public Adder Add(params int[] i) { /* ... */ }
public Adder Remove(params int[] i) { /* ... */ }

Adder adder = new Adder()
  .Add(1, 2, 3)
  .Remove(3, 4);

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

6
ответ дан 1 December 2019 в 10:04
поделиться

Цепочка - это хорошая вещь, и она является базовой в некоторых средах (например, расширения Linq и jQuery интенсивно ее используют).

Создаете ли вы новый объект или возвращаете это зависит от того, как вы ожидаете, что ваш исходный объект будет вести себя:

var a = new Adder();

var b = a.Add(4)
         .Remove(1)
         .Add(7)
         .Remove(3);

//now - should a==b ?

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

Цепочка в Linq оставит вашу исходную коллекцию без изменений. Это тоже ожидаемое поведение - каждая связанная функция является фильтром или преобразованием, и исходная коллекция часто неизменна.

Какой шаблон лучше подходит для того, что вы делаете?

2
ответ дан 1 December 2019 в 10:04
поделиться

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

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

0
ответ дан 1 December 2019 в 10:04
поделиться
  1. Для вашего конкретного случая перегрузка арифметических операторов, вероятно, будет лучшим решением.

  2. Возвращение этого (интерфейса Fluent) является обычной практикой для создания выражений - модульное тестирование и насмешливые рамки используют это много. Свободный Hibernate является еще одним примером.

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

0
ответ дан 1 December 2019 в 10:04
поделиться

Если вы назовете это Adder, я бы с возвращением это вернул. Однако для класса Adder довольно странно содержать ответ.

Вы могли бы подумать о том, чтобы сделать его чем-то вроде MyNumber и создать метод Add () -.

В идеале (IMHO), это не изменит число, хранящееся в вашем экземпляре, но создаст новый экземпляр с новым значением, которое вы возвращаете:

class MyNumber
{
    ...

    MyNumber Add( int i )
    {
        return new MyNumber( this.Value + i );
    }
}
0
ответ дан 1 December 2019 в 10:04
поделиться

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

var a = new Adder () .Add (4);

var b = a.Удалить (1);

var c = a.Add (7) .Remove (3);

В этом случае и b, и c имеют захваченное состояние в качестве отправной точки. Я столкнулся с этой идиомой, читая о шаблоне для создания объектов тестовой области в Растущее объектно-ориентированное программное обеспечение, руководствуясь тестами Стива Фримена; Nat Pryce .

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

0
ответ дан 1 December 2019 в 10:04
поделиться

Я думаю, что для простых интерфейсов "свободно "интерфейс очень полезен, особенно потому, что он очень прост в реализации. Ценность свободного интерфейса в том, что он устраняет много постороннего пуха, который мешает пониманию. Разработка такого интерфейса может занять много времени, особенно когда интерфейс начинает участвовать. Вы должны беспокоиться о том, как использование интерфейса «читает»; На мой взгляд, наиболее убедительным использованием такого интерфейса является то, как он передает намерение программиста, а не количество символов, которые он сохраняет.

Чтобы ответить на ваш конкретный вопрос, мне нравится стиль «вернуть это». Мое типичное использование беглого интерфейса - определить набор опций. То есть я создаю экземпляр класса и затем использую беглые методы в этом экземпляре, чтобы определить желаемое поведение объекта. Если у меня есть опция да / нет (скажем, для ведения журнала), я стараюсь не использовать метод setLogging (bool state), а два метода «WithLogging» и «WithoutLogging». Это немного больше работы, но ясность окончательного результата очень полезна.

0
ответ дан 1 December 2019 в 10:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: