Как представлять данные, которые не могут быть установлены - PullRequest
2 голосов
/ 14 марта 2012

У меня есть класс, содержащий ряд свойств, например:

public class Update
{
    public int Quantity { get; set; }
    public decimal Price { get; set; }
    public string Name { get; set; }
}

Каждый экземпляр Update не обязательно должен иметь каждый набор свойств, и другая часть системы должна знать, какие из них установлены, а какие нет.

Один из вариантов, который у меня есть, состоит в том, чтобы сделать все типы значений Nullable, и поэтому значение null будет представлять концепцию отсутствия установки. Хотя это сработает, мне не очень нравится идея иметь некоторые свойства явно Nullable (типы значений) и некоторые обнуляемые в силу того, что они являются ссылочным типом. Определение класса выглядело бы некрасиво, и я не уверен, что нулевая проверка является семантически лучшим подходом.

Я мог бы создать класс, очень похожий на Nullable<T>, который не имеет ограничений на T со свойством IsSet. Я предпочитаю эту опцию использованию Nullable, но я все же хотел бы посмотреть, есть ли у кого-нибудь альтернативное представление, которое лучше предложенных мной вариантов.

Ответы [ 6 ]

5 голосов
/ 14 марта 2012

Вы действительно должны придерживаться существующей здесь идиомы. Используйте встроенную обнуляемость.

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

Редактировать: Иногда вам нужно иметь возможность сделать значение необязательным в общем коде. В этом случае вам нужно использовать какой-то тип настраиваемой опции. По опыту могу сказать, что это довольно неприятно в использовании. Это не мое решение выбора.

4 голосов
/ 14 марта 2012

Типы ссылок уже , могут быть обнулены, эффективно - если вы используете int?, decimal? и string, тогда каждое из ваших свойств может быть нулевым.

Проблемаприходит, если вы когда-нибудь захотите установить значение string в нулевую ссылку - если фактически значение NULL является действительным значением, которое установлено .

Вы, конечно, могли бы написатьтипа Maybe<T>, но я не уверен, что смогу - я бы , вероятно, просто использовал бы null ... кроме всего прочего, это будет более знакомо для других, читающих код, который используется дляC # идиомы.При всех «анти-нулевых» чувствах (которые я делаю во многих ситуациях) есть случаи, когда это самый простой подход.

1 голос
/ 14 марта 2012

Я бы сказал, что Nullable - это именно то, что вы хотите использовать для этой цели.Вы можете обернуть элементы свойствами (как вы уже делаете), чтобы класс показывал обычные значения снаружи вместе с методами «is it set», чтобы проверить, если это необходимо.Но внутри я бы использовал Nullable.

1 голос
/ 14 марта 2012

Мне не очень нравится идея иметь некоторые свойства Nullable ( типы значений), а некоторые нет (ссылочные типы)

Ссылочные типы явно обнуляются.

string t = null; //is totally valid
0 голосов
/ 14 марта 2012

Решение здесь

  • использовать nullable везде, где null не является допустимым параметром
  • использовать значение по умолчанию, где null является допустимым параметром, но вы совершенно уверены, что данное значениене произойдет
  • используйте логический флаг для каждого свойства, где null является допустимым значением, и вы не можете назвать имя по умолчанию, которое никогда не будет использоваться.

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

По умолчанию имя должно иметь значение "", если имя может быть нулевым (отсутствие имени), и вы уверены, что имя никогда не будетbe ""

Флаг, скажем, nameSet должен использоваться, если Name может иметь нулевое значение и вы не можете думать о значении по умолчанию.Этот флаг был бы ложным по умолчанию, и когда вы впервые устанавливаете значение имени, этот флаг также должен быть установлен в истинное значение.

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

0 голосов
/ 14 марта 2012

Чтобы предложить вам что-то новое ... Если вы просто говорите об одном классе, таком как Update, с ограниченным числом участников, я бы использовал только IsSet.

Но если у вас есть, например, несколько похожих классов с таким поведением или много свойств, я мог бы предложить вам использовать шаблоны t4. Например, вы можете получить свойства класса (необходимого типа или атрибута), как описано в этой статье , и автоматически генерировать код на основе списка свойств (реализуя любой дизайн, который вы хотите автоматически)

Я мог бы описать это больше, если кому-то интересно ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...