Один шаблон проектирования, где ref
- это двунаправленный посетитель.
Предположим, у вас есть класс Storage
, который можно использовать для загрузки или сохранения значений различных примитивных типов. Это либо в режиме Load
, либо в режиме Save
. У него есть группа перегруженных методов с именем Transfer
, и вот пример для работы с int
значениями.
public void Transfer(ref int value)
{
if (Loading)
value = ReadInt();
else
WriteInt(value);
}
Были бы аналогичные методы для других примитивных типов - bool
, string
и т. Д.
Тогда для класса, который должен быть "переносимым", вы должны написать метод, подобный этому:
public void TransferViaStorage(Storage s)
{
s.Transfer(ref _firstName);
s.Transfer(ref _lastName);
s.Transfer(ref _salary);
}
Этот же единственный метод может загружать поля из Storage
или сохранять поля в Storage
, в зависимости от того, в каком режиме находится объект Storage
.
На самом деле вы просто перечисляете все поля, которые необходимо перенести, поэтому он приближается к декларативному программированию, а не к императиву. Это означает, что вам не нужно писать две функции (одну для чтения, другую для записи), и учитывая, что дизайн, который я здесь использую, зависит от порядка, тогда очень удобно знать, что поля всегда будут читаться / написано в одинаковом порядке.
В целом, когда параметр помечен как ref
, вы не знаете, будет ли метод читать его или записывать в него, и это позволяет вам проектировать классы посетителей, которые работают в одном из двух направления, предназначенные для вызова симметричным образом (т. е. при посещенном методе не требуется знать, в каком режиме направления работает класс посетителей).
Сравнение: атрибуты + отражение
Почему это вместо того, чтобы приписывать поля и использовать отражение для автоматической реализации эквивалента TransferViaStorage
? Потому что иногда рефлексия достаточно медленная, чтобы быть узким местом (но всегда быть профильной, чтобы быть уверенным в этом - это вряд ли когда-либо верно, а атрибуты намного ближе к идеалу декларативного программирования).