Добавление null в список <bool?>, Приведенный как IList, создающий исключение - PullRequest
12 голосов
/ 16 декабря 2009

Использование .NET 3.5 и C # 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]");

Ответы [ 6 ]

14 голосов
/ 16 декабря 2009

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

3 голосов
/ 16 декабря 2009

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

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

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

1 голос
/ 16 декабря 2009

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

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

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

IList<bool?> list = new List<bool?>();
list.Add(null);
1 голос
/ 16 декабря 2009

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

0 голосов
/ 12 ноября 2010

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

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

IList list = new List<bool?>();
MethodInfo addMethod = list.GetType().GetMethod("Add");
addMethod.Invoke(list, new object[] { null });
0 голосов
/ 16 декабря 2009

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

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