Ответ 1
Вы можете избежать использования null и создать специальный класс значений Singleton, который делает то же самое. Например:
public sealed class Nothing
{
public static readonly Nothing Value = new Nothing();
private Nothing() {}
}
Dictionary<object, string> dict = new Dictionary<object, string>();
dict.add(Nothing.Value, "Nothing");
dict.add(1, "One");
Этот подход не сработает, если вы намерены сделать вашу коллекцию более строго типизированной - скажем, например, вы хотите, чтобы ключ был строкой. Поскольку строка запечатана, вы не можете наследовать ее, чтобы создать замену "специального значения" для null. Ваши альтернативы становятся немного сложнее. Вы могли:
- Создайте специальное значение константы для представления "пустого" / "нулевого" случая. Вид хаки и определенно путь к путанице. Это может быть жизнеспособным подходом, если словарь полностью закрыт для какого-либо класса реализации, и вы можете написать некоторые методы утилиты Encode/Decode, чтобы не распространять знания о том, как вы переводите ключи по всему месту.
- Создайте собственную реализацию IDictionary, которая внутренне делегирует экземпляр Dictionary < > , за исключением случая null. Это нарушает документированные ожидания для интерфейса IDictionary < > , который говорит, что пустые ключи должны генерировать исключение. Но вы можете уйти от него, если это единственный способ решить вашу настоящую проблему. Это работает только в том случае, если вы владеете и создаете экземпляр словаря.
- Найдите способ решить вашу проблему без сохранения "нулевого" ключа в словаре. Например, рассмотрите вопрос о том, чтобы не заполнять нулевой ключ в словаре и иметь некоторую специальную логику случая для решения этой проблемы. Ключи должны быть хешируемыми и сопоставимыми с работой с базовой реализацией, поэтому нуль запрещается в обычном режиме.
Как в стороне, действительно ли ваш словарь-ключ действительно нужен для ключа object
? Это может привести к незначительным ошибкам из-за использования ссылочного равенства, когда вы можете предполагать, что Equals() оценивается как основа для сравнения.