Что, если я хочу не сохранить Ни один, оценивает в кэш-памяти?

Рекомендации MSDN для стандартных исключений гласят:

Использовать значение для имени параметра неявного значения установщиков свойств.

В следующем примере кода показано свойство, которое выдает исключение, если вызывающая сторона передает нулевой аргумент.

public IPAddress Address
{
    get
    {
        return address;
    }
    set
    {
        if(value == null)
        {
            throw new ArgumentNullException("value");
        }
        address = value;
    }
}

Кроме того, в руководящих указаниях MSDN по проектированию свойств говорится:

Избегайте создания исключений из методов получения свойств.

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

Допустимо и допустимо генерировать исключения из установщика свойств.

Итак, бросьте ArgumentNullException в установщик на null, ArgumentException в пустую строку и ничего не делайте в получателе. Поскольку сеттер выбрасывает и только у вас есть доступ к вспомогательному полю, легко убедиться, что оно не будет содержать недопустимое значение. Иметь метательный бросок бессмысленно. Однако это может быть хорошим местом для использования Debug.Assert .

Если вы действительно не можете предоставить подходящее значение по умолчанию, то я полагаю, у вас есть три варианта:

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

  2. Заменить свойство методами: метод установки, который выдает, когда передано недопустимое значение, и метод получения, который выдает InvalidOperationException, когда свойству никогда не назначалось допустимое значение.

  3. Бросьте InvalidOperationException из геттера, так как вы можете считать «свойство никогда не было назначено» как недопустимое состояние. Хотя обычно вы не должны бросать из получателей, я полагаю, что это может быть хорошей причиной для исключения.

Если вы выбираете опции 2 или 3, вы должны также включить TryGet-метод, который возвращает значение bool, которое указывает, было ли для свойства установлено допустимое значение, и, если это так, возвращает это значение в out параметр. В противном случае вы заставляете абонентов быть готовыми обработать InvalidOperationException, если только они сами не установили свойство и не знали, что оно не сгенерирует. Сравните int.Parse с int.TryParse.

Я бы предложил использовать вариант 2 с методом TryGet. Это не нарушает каких-либо правил и накладывает минимальные требования к вызывающему коду.


О других предложениях
ApplicationException слишком много общего. ArgumentException является слишком общим для null, но в остальном хорошо. MSDN снова документы :

Выдает самое конкретное (наиболее производное) исключение, которое уместно. Например, если метод получает пустой аргумент (Nothing в Visual Basic), он должен вызвать исключение System.ArgumentNullException вместо своего базового типа System.ArgumentException.

На самом деле вам вообще не следует использовать ApplicationException ( документы ):

Извлекать пользовательские исключения из T: System. Класс исключения, а не класс T: System.ApplicationException.

Первоначально считалось, что пользовательские исключения должны быть производными от класса ApplicationException; однако, это не было найдено, чтобы добавить значительную ценность. Для получения дополнительной информации см. Рекомендации по обработке исключений.

InvalidOperationException предназначен не для случаев, когда аргументы метода или свойства недопустимы, а для случаев, когда операция в целом недопустима ( документ ). Его не следует выбрасывать из установщика:

Не вызывать исключение System.InvalidOperationException, если он находится в неподходящем состоянии. System.InvalidOperationException должно быть выброшено, если набор свойств или вызов метода не подходят, учитывая текущее состояние объекта. Например, запись в System.IO.FileStream, который был открыт для чтения, должна вызвать исключение System.InvalidOperationException.

Между прочим, InvalidOperationException для случая, когда операция недопустима для текущего состояния объекта. Если операция всегда недопустима для всего класса, вы должны использовать NotSupportedException .

10
задан jamtoday 21 May 2009 в 21:50
поделиться

3 ответа

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

7
ответ дан 4 December 2019 в 01:03
поделиться

Not really.

You could store a None value as an empty string, but there isn't really a way to store special data in a memcache.

What's the difference between the cache key not existing and the cache value being None? It's probably better to unify these two situations.

0
ответ дан 4 December 2019 в 01:03
поделиться

Вы можете сделать что-то вроде того, что делают Haskell и Scala, и сохранить словарь Option. Словарь содержит два ключа: один ключ, указывающий, что он действителен, и один ключ, который используется для хранения данных. Примерно так:

{valid: true, data: whatyouwanttostore}

Тогда, если get вернет None, вы знаете, что кеш был пропущен; если результатом является словарь с None в качестве данных, значит, вы знаете, что данные были в кэше, но были ложными.

4
ответ дан 4 December 2019 в 01:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: