Подтвердить что ты не робот

Добавление значения null в список <bool?> Как IList, бросающий исключение

Использование .NET 3.5 и С# 3.0,

IList list = new List<bool?>();
list.Add(null);

Это вызывает исключение ArgumentException, которое просто кажется неправильным.

List<bool?> list = new List<bool?>();
list.Add(null);

Работает отлично.

Является ли это ошибкой в ​​коде Microsoft?

Пример того, как произвести такую ​​ошибку в реальной ситуации:

new JavaScriptSerializer().Deserialize<List<bool?>>("[true, false, null]");
4b9b3361

Ответ 1

Да, это так. См. http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/abc99fb5-e218-4efa-8969-3d96f6021cee/ для других отчетов. В основном, когда вы получаете доступ к List<bool?> через его слабо типизированную реализацию IList, он выполняет некоторую проверку типов, прежде чем пытаться добавить элемент во внутреннее хранилище, - и он проверяет этот тип неправильно для типов с нулевым значением.

Ответ 2

Это "по дизайну" и явно так. Причина в том, что List<T> имеет явную реализацию IList. Он фильтрует значения, переданные различным методам, для выполнения нулевой проверки. Логика в основном такова:

if (default(T) != null && value == null) { throw ... }

В этом случае значение по умолчанию для типа значения (и nullable - тип значения) не равно null, поэтому оно не разрешено.

Ответ 3

Ха! Это смешно. Я полагаю, что это связано с идеей о том, что nullable bool, строго говоря, реализуется как структура, а IList ожидает объект, и, возможно, он ожидает, чтобы вставить bool или что-то еще. Джон Скит, где ты? Мы нуждаемся в вас! (краны рубиновые тапочки 3 раза)

Ответ 4

Когда вы вызываете метод Add в IList с нулевым значением, это пустая ссылка, которую вы передаете методу, а не значение NULL. Нулевая ссылка не может быть преобразована в значение с нулевым значением.

Метод Add ожидает нечто, содержащее bool или bool?. Поскольку вы не можете ввести нулевое значение, вы не можете создать объект, который можно использовать для добавления нулевого значения в IList.

Если вы используете общий интерфейс IList<bool?> вместо этого, нет проблем с добавлением значения:

IList<bool?> list = new List<bool?>();
list.Add(null);

Ответ 5

Как уже отмечалось, в реализации метода IList.Add(объект объекта) в классе List <T> в .NET 3.5 (а может быть и раньше) есть ошибка. Дело в том, что метод IList.Add(объект объекта) пытается проверить, что объект, который мы пытаемся добавить, является объектом, совместимым с аргументом Generic типа <T>, который терпит неудачу, когда мы пытаемся добавить null к списку типов допустимых значений.

Мое обходное решение включает отражение, получая и вызывая метод Add (T item) из объекта List.

IList list = new List<bool?>();
MethodInfo addMethod = list.GetType().GetMethod("Add");
addMethod.Invoke(list, new object[] { null });

Ответ 6

Вы смешиваете Generic List<T> с не общим IList. List<T> наследуется от IList<T>, а не от IList.