Объединение команд в цепочку путем возврата этого указателя / ссылки в C # без присваивания

В основном это вопрос синтаксиса. Вот связанный поток, показывающий различные альтернативы для достижения того же результата: Цепочка методов в C #

Теперь в C ++ можно связывать команды с объектом, заставляя методы возвращать указатель на объект, членом которого является метод.

Синтаксис, который я ищу:

foo.Transform(bar).TransformDifferently(yay);

В C #, если я верну это, значение будет скопировано (изменить: наполовину неверно, прочитать ответы). Я не думаю, что могу вернуть ссылку или указатель, не так ли? Есть ли другой способ добиться того же синтаксиса?

На данный момент мое решение - просто присвоить результат моему объекту, например:

foo = foo.Transform(bar).TransformDifferently(yay);

Однако это не оптимальное решение, потому что оно и медленнее (в моем случае не имеет значения), и более подробное. Буду очень рад любым указателям в правильном направлении!


person Martin Grönlund    schedule 16.07.2013    source источник


Ответы (3)


В C #, если я верну это, значение будет скопировано

Это не так, по крайней мере, для классов. Классы в C # являются ссылочными типами, это означает, что каждая переменная этого типа на самом деле является ссылкой, поэтому возвращение this просто возвращает ссылку на текущий экземпляр.

Для этого в C #, по сути, то же самое:

public class Foo
{
    public Foo Transform(Bar bar)
    {
        // transform
        return this;
    }

    public Foo TransformDifferently(Yay yay)
    {
        // transform
        return this;
    }
}

Для типов значений он должен возвращать новый экземпляр типа. Типы значений должны быть неизменяемыми, поэтому, если вы правильно спроектировали свой struct, не должно быть никакого метода, изменяющего оригинал. Вместо этого Transform следует изменить новую версию структуры.

person p.s.w.g    schedule 16.07.2013
comment
Отлично, спасибо большое! Моя ошибка - я думал, что единственная разница между структурами и классами - это стандартные модификаторы видимости (опять же, как в C ++, хе-хе). - person Martin Grönlund; 16.07.2013

В C #, если я верну это, значение будет скопировано

Неправильно. Указатель this относится к «текущему» объекту и не создает глубокую или неглубокую копию объекта.

Итак, это:

foo.Transform(bar).TransformDifferently(yay);

работает отлично.

person Maarten    schedule 16.07.2013
comment
Спасибо, +1 за упоминание глубокой и поверхностной копии! - person Martin Grönlund; 16.07.2013

Какого типа ваша переменная foo? Это класс или экземпляр структуры?

Если это экземпляр класса, вы можете получить искомый синтаксис, вернув this. Объект не будет скопирован. 'this' - это ссылка, именно такая, как вы ожидаете.

Если foo является экземпляром структуры, то то, чего вы пытаетесь достичь, - плохая идея. Рекомендуется делать структуры неизменяемыми, чтобы мы могли рассуждать о них как о примитивах (целые числа, логические значения и т. Д.). В этом случае вам лучше вернуть копию.

person Reda    schedule 16.07.2013
comment
Это была структура, но теперь я изменил ее на класс. Спасибо и +1 за подсказку о неизменности примитивов! - person Martin Grönlund; 16.07.2013
comment
Неважно, что я сказал, я снова изменил его на структуру - просто из-за того, что вы сказали о примитивах. - person Martin Grönlund; 16.07.2013
comment
Вы возвращаете this или новую копию своей структуры? - person Reda; 16.07.2013
comment
this - но, кажется, это новая копия, когда я ее верну. - person Martin Grönlund; 16.07.2013