Если у меня есть стандартная программа, которая может бросить ArgumentException в два места, что-то как...
if (Var1 == null)
{
throw new ArgumentException ("Var1 is null, this cannot be!");
}
if (Val2 == null)
{
throw new ArgumentException ("Var2 is null, this cannot be either!");
}
Каков лучший способ определить в моей процедуре вызова, которая из этих двух исключений была брошена?
Или
Я делаю это неправильным способом?
Передайте имя переменной (Val1, Val2 и т. Д.) Во втором аргументе конструктору ArgumentException. Это становится свойством ArgumentException.ParamName.
Ваша вызывающая функция не должна заботиться о том, какая строка вызвала исключение. В любом случае возникло исключение ArgumentException
, и оба должны обрабатываться одинаково.
Используйте конструктор ArgumentException (строка, строка) , чтобы определить, какой параметр имеет значение NULL.
if (Var1 == null) {
throw new ArgumentException ("Var1 is null, this cannot be!","Var1");
}
if (Val2 == null){
throw new ArgumentException ("Var2 is null, this cannot be either!","Var2");
}
Что ж, для ArgumentException, в частности, у вас есть параметр, для которого возникла проблема с аргументом:
throw new ArgumentException("Var1 is null, this cannot be!", "Var1");
В более общем смысле вы обычно делаете что-то вроде использования другого (возможно, custom) типов исключений, и тогда вызывающий код может иметь разные блоки catch
public class MyCustomException1 : ApplicationException {}
public class MyCustomException2 : ApplicationException {}
try
{
DoSomething();
}
catch(MyCustomException1 mce1)
{
}
catch(MyCustomException2 mce2)
{
}
catch(Exception ex)
{
}
Более важный вопрос, который вы должны задать себе, - почему? Если вы пытаетесь избавиться от какой-то логики, исключения, как правило, не подходят.
Скорее, у вас должен быть тип возвращаемого значения (или параметр out / ref), который будет установлен с флагом / значением какого-либо типа, который вы можете определить из вызывающего кода, чтобы определить, что это за ошибка, и избавиться от этой логики. .
Если вы настаиваете на использовании исключений, то в этом случае ArgumentNullException имеет конструктор, который принимает имя параметра и сообщение об исключении . Вы можете вызвать исключение, а затем, перехватив исключение, получить доступ к свойству ParamName , чтобы определить имя параметра, вызвавшего исключение.
Вы действительно не предоставляете достаточно информации, чтобы ответить на ваш вопрос. Очевидный ответ - посмотреть на сообщение об исключении, но я предполагаю, что это не то, что вы ищете.
Если действительно важно, чтобы вы могли программно различать их, используйте другое исключение или, по крайней мере, используйте свойство paramName
конструктора текущего исключения. Это даст вам несколько более актуальную информацию.
Однако использование вашего собственного типа исключения - единственный способ гарантировать, что вы перехватываете исключение для определенных обстоятельств . Поскольку ArgumentException
является частью фреймворка, возможно, что что-то еще, что вы вызываете, может вызвать его, что приведет вас к тому же блоку catch. Если вы создадите собственный тип исключения (один для обоих или по одному для каждого из сценариев), это предоставит вам способ обработки конкретной ошибки.Конечно, судя по вашему примеру, кажется, что было бы проще просто проверить и увидеть, является ли Val1
или Val2
нулевым, прежде чем вызывать функцию для начала.
При бросании ArgumentExceptions
вы всегда можете включить имя аргумента, вызывающего исключение (это другой конструктор). Конечно, я предполагаю, что вы действительно хотите узнать, какой из аргументов был нулевым, и в этом случае вам, вероятно, следует использовать ArgumentNullException.
Если это тестовый пример, когда вы хотите убедиться, что отображается правильное сообщение об исключении, я знаю, что NUnit имеет ключевое слово ExpectedMessage
для атрибута ExpectedException
. В противном случае ArgumentNullException
является ArgumentNullException
, и ваше приложение должно обрабатывать их все одинаково. Если вам нужны более подробные сведения, создайте свои собственные классы исключений и используйте их.
Таким образом, вы можете проверить следующее:
[ExpectedException(typeof(ArgumentNullException), ExpectedMessage="Var1 is null, this cannot be!"]
public void TestCaseOne {
...
}
[ExpectedException(typeof(ArgumentNullException), ExpectedMessage="Var2 is null, this cannot be either!"]
public void TestCaseTwo {
...
}
try
{
//code here
}
catch (ArgumentException ae)
{
Console.WriteLine(ae.ToString());
}
Вывод в вашей консоли покажет, какое сообщение вы поместили.
Для этого конкретного сценария вы должны использовать ArgumentNullException
и правильно заполнить его свойство ParamName
, чтобы вы знали аргумент, который является нулевым.
Класс ArgumentException
также поддерживает это свойство, но вы должны использовать наиболее специфичный тип исключения.
При использовании этих типов исключений также будьте осторожны при использовании конструктора, который принимает как сообщение, так и имя параметра. Порядки меняются между каждым типом исключений:
throw new ArgumentException("message", "paramName");
throw new ArgumentNullException("paramName", "message");