Разработка метода с использованием ref для изменения частично неизменяемого класса - PullRequest
4 голосов
/ 10 августа 2011

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

Ниже приведен пример хранения некоторой информации в классе транспорта данных и запроса ее обратно.

var header = new IntvlDataHeader(
       datapoint: Guid.NewGuid(),
       element: Guid.NewGuid(),
       intervalUtc: DateTime.Now.Date);

package.StockData_Decimal(header, 5m);

decimal cloneData;
package.TryGetData_Decimal(ref header, out cloneData);

// header now refers to a different object, that could have different flags/information

Обратите внимание, как я заставил TryGetData_Decimal передавать переменную заголовка по ссылке. IntvlDataHeader является классом, и если данные находятся внутри TryGetData, то ссылка изменяется, чтобы указывать на новый экземпляр IntvlDataHeader, который содержит информацию конкретного экземпляра в дополнение к той же информации уникального ключа.

Является ли сочетание ключа с информацией, специфичной для экземпляра, и использование параметра ref как плохим, как внутри, так и снаружи? Будет ли попытка разделить другой класс так, чтобы было два выходных параметра и никакие ref-параметры лучше или избежать каких-либо потенциальных проблем?

Подпись метода public bool TryGetData_Decimal(ref IntvlDataHeader header, out decimal data)

1 Ответ

2 голосов
/ 10 августа 2011

Я думаю, что наименование вашего TryGetData_Decimal вводит в заблуждение, если параметр ref, который вы передаете, будет указывать на новый экземпляр при выходе из метода. Для меня TryGetData_Decimal звучит как изменение методов TryParse для ряда типов значений (в которых есть параметр out, содержащий проанализированное значение - аналогично параметру cloneData).

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

IntvlDataHeader ExtractValueAndGetNewInstance_Decimal(IntvlDataHeader header, out decimal cloneData)

где передается заголовок, но не изменяется при выходе из метода. Метод возвращает новый экземпляр, и вы можете использовать его, если вам это нужно. Я бы не стал изменять cloneData - я думаю, что параметры out в порядке, если они не используются слишком много.

Я бы тоже попытался изменить название метода на что-то более значимое.

Надеюсь, это поможет.

...