Как представлять данные, которые не могут быть установлены

StackOverflow https://stackoverflow.com//questions/9704435

Вопрос

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

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

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

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

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

Это было полезно?

Решение

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

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

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

Другие советы

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

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

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

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

Ссылочные типы, очевидно, допускают значение NULL.

string t = null; //is totally valid

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

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

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

Могу описать подробнее, если интересно...

Решение здесь, чтобы

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top