Это классическая проблема, с которой сталкивается каждый разработчик C #.
Позвольте мне разбить ваш вопрос на 2 вопроса. Первый,
Можно ли поймать несколько исключений одновременно?
Короче говоря, нет.
Что приводит к следующему вопросу,
Как мне избежать написания дублирующего кода, если я не могу перехватить несколько типов исключений в одном блоке catch ()?
Учитывая ваш конкретный пример, где резервное значение дешево построить, я хотел бы выполнить следующие шаги:
Таким образом, код выглядит следующим образом:
try
{
WebId = Guid.Empty;
Guid newGuid = new Guid(queryString["web"]);
// More initialization code goes here like
// newGuid.x = y;
WebId = newGuid;
}
catch (FormatException) {}
catch (OverflowException) {}
Если выбрасывается какое-либо исключение, то WebId никогда не устанавливается на половину построенного значения и остается Guid.Empty.
Если построение запасного значения стоит дорого, а сброс значения намного дешевле, я бы переместил код сброса в его собственную функцию:
try
{
WebId = new Guid(queryString["web"]);
// More initialization code goes here.
}
catch (FormatException) {
Reset(WebId);
}
catch (OverflowException) {
Reset(WebId);
}
Просто создайте новый класс и верните этот класс
class Result
{
A* a;
int i;
public:
Result( A*a, int i ) : a(a), i(i) {
}
~Result() {
delete a;
}
// access functions, copy constructor, ...
};
Result getA() {
//...
return Result(new A, intValue);
}
Есть два основных способа решить эту проблему:
shared_ptr
. auto_ptr
, как вы обнаружили, на самом деле не работает в таких случаях, но новый стандарт и Boost содержат указатели с подсчетом ссылок, которые делают то, что вы хотите. Сообщите нам, что вам не нравится в shared_ptr
, и, возможно, мы предложим альтернативу.
A shared_ptr
был бы идеальным в этой ситуации, но если вы действительно не хотите их использовать, вы можете вернуть auto_ptr
паре вместо этого содержащий объект и int.
Почему не через два эталонных параметра?
class AGetter
{
// ..
void get(std::auto_ptr<A>& a, int& i)
{
a = a_.release();
i = i_;
}
// ..
};
Это некрасиво, но вы можете вернуть другое значение с помощью аргумента указателя или ссылки:
int i;
std::auto_ptr<A> a = getA(&i);