Если вы делаете это много и хотите, чтобы у вас был эквивалентный бросок без исключения, попробуйте:
public static class Catching<TException> where TException : Exception
{
public static bool Try<T>(Func<T> func, out T result)
{
try
{
result = func();
return true;
}
catch (TException x)
{
// log exception message (with call stacks
// and all InnerExceptions)
}
result = default(T);
return false;
}
public static T Try<T>(Func<T> func, T defaultValue)
{
T result;
if (Try(func, out result))
return result;
return defaultValue;
}
}
Так что теперь вы можете сделать это:
Foo.Bar newObj;
if (!Catching<ComException>.Try(() => new Foo.Bar(), out newObj))
{
// didn't work.
}
Или, если у вас есть объект по умолчанию, хранящийся в defaultMyInterface
, вы бы использовали его для реализации интерфейса, если нет ничего лучше:
IMyInterface i = Catching<ComException>.Try(() => new Foo.Bar() as IMyInterface,
defaultMyInterface);
Вы также можете сделать это в совершенно другом сценарии:
int queueSize = Catching<MyParsingException>
.Try(() => Parse(optionStr, "QueueSize"), 5);
Если Parse
выдает MyParsingException
, queueSize
будет по умолчанию равным 5
, в противном случае используется возвращаемое значение из Parse
(или любое другое исключение будет распространяться нормально, что обычно является тем, что вы хотите с неожиданное исключение).
Это помогает избежать нарушения потока кода, а также централизует вашу политику ведения журналов.