Почему Перечислимым.SequenceEqual вызывает исключение, если какой-либо параметр равен null?
Я пытался использовать Enumerable.SequenceEqual(x,y)
Как я ожидал, он будет работать на основе
Object.Equals(x,y)
метод, который возвращает false, если x или y равно null, и true, если оба равно null (для нулевых случаев).
Enumerable.SequenceEqual(x,y)
создает исключение, если какой-либо параметр является нулевой ссылкой и не возвращает true, если ему задано два нуля.
в моем коде я часто проверяю равенство коллекции, поэтому я создал метод, который имитирует Object.Equals
поведение для последовательностей, но мне просто интересно, какова логика такое поведение по умолчанию, и есть ли, возможно, существующий метод без исключений для нулей?
2 ответов
Ну документация MSDN явно указывает, что он бросает ArgumentNullException
в случае, если любой из переданных последовательностей равен null. Я предполагаю, что это должно поддерживать согласованность со "стандартным поведением", когда объект бросает NullReferenceException
когда вы пытаетесь разыменовать его. Рассматривайте это:
List<int> foo = null;
foo.SequenceEqual(new List<int>());
Это было бы хорошо, как SequenceEqual
является методом расширения и поэтому может обрабатывать нулевой объект, но это также было бы запутанным. Каждый метод расширения, предоставляемый Linq, следует этому поведение, насколько я знаю. Также вам не нужно обрабатывать специальные нулевые случаи для каждого метода расширения (вам нужно будет согласиться с разумным поведением и добавить дополнительную логику и поддерживать и тестировать ее). Говоря, что это незаконно, делает его более надежным (против логических ошибок) и последовательным с точки зрения фреймворка. Я много использую Linq и никогда не сталкивался с этой проблемой - я просто удостоверяюсь, что все мои последовательности не равны нулю. Уменьшает беспорядок кода (удаляет много нулевых проверок из кода).
точка, в которой он проверяет равенство последовательности, не является, когда это исключение создается. Он выбрасывается ранее в качестве аргумента validator. Рассмотрим метод:
public static bool SequenceEquals<T>(this IEnumerable<T> source, IEnumerable<T> target)
{
// Stuff
}
нам явно нужно проверить это source
и target
не являются null, потому что если любой из них, то мы не могу проверьте равенство последовательности. Это неработоспособное состояние, и результат SequenceEquals
должны регулироваться содержание enumerables, а не государство из enumerables. Если бы он включал последнее, при возвращении false
, как бы вызывающий знал, действительно ли он терпит неудачу, потому что последовательности не равны, или один или оба перечисляемых являются null
?
если бы мы не бросили ArgumentNullException
здесь CLR бросил бы NullReferenceException
при попытке доступа к одному из null
enumerables. Просто говоря Object reference not set to an instance of an object
гораздо менее полезно, чем The argument <something> cannot be null
.
помните, что тип создаваемого исключения как правило, один из самых полезных индикаторов о почему исключение.