Это плохая практика для метода класса возвращать `это`?

#c# #oop #return #this #fluent

#c# #ооп #Возврат #это #свободно

Вопрос:

 public class Chain
{
    public string ChainString;

    public Chain() 
    {
        ChainString = "{}"; 
    }

    public Chain AddLink()
    {
        ChainString  = "-{}";
        return this; // is this a bad idea?
    }
}
 

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

 // more verbose (here, `AddLink` returns void)
Chain myChain = new Chain();
myChain.AddLink();
myChain.AddLink();
myChain.AddLink();
// myChain.ChainString = "{}-{}-{}-{}"
 
 // nicer
Chain myChain = new Chain()
    .AddLink()
    .AddLink()
    .AddLink();
// myChain.ChainString = "{}-{}-{}-{}"
 

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

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

1. Разве это не должно быть public static Chain NewChain() ?

Ответ №1:

Нет. Это обычный шаблон для fluent интерфейсов.

Ответ №2:

Это нормально. Могу ли я также предложить:

 public Chain AddLink(int links = 1)
{
    if (links <= 0) return this;

    string link = "-{}";
    var buf = new StringBuilder(ChainString, ChainString.Length   (links * link.Length));
    for(int i=0; i<links; i  )
    {
        buf.Append(link);
    }

    ChainString = buf.ToString();
    return this; 
}
 

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

1. Выше был всего лишь пример, я на самом деле не создаю цепочки. Хотя спасибо.

Ответ №3:

Как было опубликовано выше, это очень распространенный шаблон проектирования, который направлен на то, чтобы сделать код более читаемым. Вы можете найти несколько терминов, используемых для описания такого кода (плавное кодирование, свободный стиль, свободный api, свободный интерфейс). С другой стороны, отлаживать сложно, а иногда даже невозможно. Промежуточные результаты недостижимы.

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

1. как так? Вы можете легко входить / выходить при работе с этой идиомой и видеть каждый промежуточный результат.

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

3. невозможность отладки внешней библиотеки не относится к цепочке.