Какой тип исключения выбрасывать, если список / коллекция пуста или пуста и не может быть повторена (не параметр)?
предположим простой пример, когда метод извлекает коллекцию (например, список, содержащий некоторые строки конфигурации) и пытается каким-то образом ее изучить:
void Init()
{
XmlDocument config = new XmlDocument();
config.Load(someXml);
var list = config.SelectNodes("/root/strings/key"); // Normally, list should not be null or empty
if (list == null || list.Count == 0)
throw new SomeExceptionType(message); // What kind of exception to throw?
// Iterate list and process/examine its elements
foreach (var e in list) ...
}
в этом конкретном случае метод не может продолжаться нормально, если ничего не было извлечено. Я не уверен, какой тип исключения бросить в таких ситуациях. Мои варианты, насколько я знаю:
ничего не бросать вручную, и пусть
NullReferenceException
быть брошенным автоматически (который не обрабатывает ситуации пустой список),throw пользовательский тип исключения (вероятно, не очень хорошая идея, так как я не ожидаю, что вызывающий абонент попытается что-либо сделать с исключением, т. е. он не будет искать speecific тип исключения для обработки),
- сделать что-то еще?
3 ответов
Вы можете создать свой собственный тип исключения для соответствующей логики:
public class InitializationException : Exception
{
}
и затем:
throw new InitializationException {Message = "Collection is empty"};
Я не уверен, что есть одно встроенное исключение, которое вы можете элегантно бросить в этом случае...а NullReferenceException
неуместно, так как пустой список не является нулевой ссылкой
Я бы предложил пойти с предложенным решением Dmintry, так как вызывающий абонент все еще может просто использовать try...catch(Exception)
без необходимости знать или заботиться о том, что исключение действительно SuperDooperListNullOrEmptyFunTimeException
поскольку это либо неустранимая ошибка с точки зрения вызывающего абонента (i.e они не имеют никакого контроля над выбранными Xml-путь и отсутствие контроля над тем, что такое XML, который загружается), то исключение будет только сбрасываться в журнал или на экране для потребления человеком, и в этот момент это спорно, поскольку фактическое сообщение более важно, чем тип.
С другой стороны, если он восстанавливается (вызывающий может повторно попробовать метод после того, как убедился, что xml для загрузки теперь содержит правильно отформатированный xml, или вызывающий может уведомить Пользователя и попросить их пойти и исправить XML и " будет хочешь повторить попытку?"вроде того) тогда ты нужно чтобы дать им типизированное исключение, чтобы они знали, что безопасно повторить попытку, а не простое старое исключение, которое может означать, что что-то еще пошло ужасно неправильно, и повторная попытка только ухудшит ситуацию...
Это не большая часть проблемы программирования, поскольку это проблема дизайна, причина .NET list object не бросают исключения, когда они пусты, потому что есть много случаев, когда пустой список является ожидаемой и приемлемой ситуацией.
Если в контексте список, с которым вы работаете, никогда не должен быть пустым, тогда бросьте исключение (пользовательское)
Если, однако, вполне возможно, и логично, что список может быть пустым, зачем прерывать все это, это не исключено исключительный, так нужно исключение ? А foreach
цикл и пустой список не будут создавать исключения, цикл просто не будет циклическим.
Что касается нулевой возможности (довольно редко для SelectNodes
если хорошо понять) это та же проблема, в некоторых библиотеках или функциях, возвращающих null
нормальное поведение не является исключением.