Недавно я разрабатываю программное обеспечение, которое анализирует и отображает информацию XML с веб-сайта. Достаточно простое право?
Я получаю ЗАГРУЗКИ NullReferenceExceptions. Например, этот метод:
private void SetUserFriends(List<Friend> list)
{
int x = 40;
int y = 3;
if (list != null)
{
foreach (Friend friend in list)
{
FriendControl control = new FriendControl();
control.ID = friend.ID;
control.URL = friend.URL;
control.SetID(friend.ID);
control.SetName(friend.Name);
control.SetImage(friend.Photo);
control.Location = new Point(x, y);
panel2.Controls.Add(control);
y = y + control.Height + 4;
}
}
}
Я должен был перенести ужасное как грех, Если вокруг фактического цикла foreach для предотвращения исключения.
Я чувствую, что просто помещаю лейкопластыри на спущенную шину вместо того, чтобы на самом деле решить проблему. Есть ли какой-либо способ, которым я могу заняться этой проблемой? Возможно, книга я должен читать относительно шаблонов программирования или что нет?
Действительно, я потерян. Я, вероятно, задаю неправильные вопросы.
Похоже, вы не знаете, что делать, если вы получаете неверные параметры в своих методах. По сути, в том, что вы делаете сейчас, нет ничего плохого, но более распространенным шаблоном является проверка параметров в заголовке вашего метода, выдача исключения, если они не соответствуют вашим ожиданиям:
if (list == null)
{
throw new ArgumentNullException(list);
}
Это обычная защита шаблон программирования - убедитесь, что предоставленные вами данные проходят базовую проверку работоспособности.
Теперь, если вы сами явно вызываете этот метод и обнаруживаете, что этот метод получает параметр null list
, когда вы этого не ожидаете, пора взглянуть на логику метод вызова. Лично я предпочитаю передавать пустой список, когда у меня нет элементов, в отличие от null
, чтобы избежать особых случаев, подобных этому.
Также при выдаче исключений ArgumentNullException есть также нечто, называемое «Шаблон Null Obejct», который вы можете использовать, если вы хотите, чтобы передавал нулевое значение, например, чтобы указать, что чего-то не существует, но не Я не хочу явно проверять нули. По сути, это класс-заглушка, который реализует тот же интерфейс, но его методы обычно либо пусты, либо возвращают ровно столько, чтобы они завершились. http://en.wikipedia.org/wiki/Null_Object_pattern
Также полезно для типов значений, которые не могут легко выразить свое несуществование, не имея возможности быть нулевым.
Я бы возвращался раньше (или выбрасывал InvalidArgumentException раньше), когда вводится недопустимая информация.
Например:
private void SetUserFriends(List<Friend> list)
{
if (list == null)
return;
/* Do stuff */
}
В качестве альтернативы вы можете использовать общий шаблон коалесцирования нулей:
private void SetUserFriends(List<Friend> list)
{
list = list ?? new List<Friend>();
/* Do Stuff */
}
Я, вероятно, получу отрицательное голосование от толпы «без множественного выхода», но я обычно справляюсь с этим с помощью простой проверки в самом начале метода:
if (list == null || list.Count == 0) return;
здесь указываются условия выхода, а затем вы этого не делаете. нужно беспокоиться о нескольких уровнях отступа в вашем методе. Это работает только в том случае, если вы можете позволить себе проглотить тот факт, что ваш список пуст или равен нулю, что может случиться в некоторых случаях.
Но я согласен с кодекой в том смысле, что вам нужно взглянуть на вызывающий код и подумать, можно ли оттуда его улучшить.
Похоже, что защитное программирование и проверка параметров - это то, что вам нужно.
Как говорили другие, для вас подойдет простая проверка параметров:
if (list == null)
throw new ArgumentNullException("list");
В качестве альтернативы, если вы устали постоянно писать подобные проверки для каждого параметра, вы можете проверить одну из многих библиотек принудительного исполнения предварительных условий .NET с открытым исходным кодом. Мне нравится CuttingEdge.Conditions .
Таким образом, вы можете использовать что-то вроде этого:
Condition.Requires(list, "list").IsNotNull();
Однако установка предварительного условия, подобного любому из вышеперечисленных, просто укажет, что ваш метод не принимает значения NULL. Ваша проблема по-прежнему будет заключаться в том, что вы передаете в метод значения NULL! Чтобы исправить это, вам нужно будет изучить, что вызывает ваши методы, и выяснить, почему передаются нулевые объекты.