Как красивее сделать обертку для Exception-derived class?
Пишу свой класс, унаследованный от Exception. Использоваться он будет примерно так:
try
{
.....
}
catch(SqlException sex)
{
SMSADVException ex2 = new SMSADVException(sex);
Common.WriteErrorInfo(ex2);
if (sqt != null)
sqt.Rollback();
}
public void WriteErrorInfo(Exception ex)
{
if (ex is SMSADVException)
{
...
}
}
Соответственно, в конструкторе надо скопировать все интересные мне поля из переданного параметра. Как это будет лучше всего сделать?
Здравствуйте, Lloret, Вы писали:
L>Как красивее сделать обертку для Exception-derived class?
L>Пишу свой класс, унаследованный от Exception. Использоваться он будет примерно так:
L>L> public void WriteErrorInfo(Exception ex)
L> {
L> if (ex is SMSADVException)
L> {
L> ...
L> }
L> }
L>
Мне вот это не нравится, нарушается принцип открытия-закрытия. Используй виртуальные методы лучше или еще что...
Что касается вопроса про конструктор...
Может и не надо ничего копировать то?
В System.Exception есть
public Exception InnerException {get;} и
public Exception(string message, Exception innerException)... << RSDN@Home 1.1.3 stable >>
Здравствуйте, Lloret, Вы писали:
L>Как красивее сделать обертку для Exception-derived class?
L>Пишу свой класс, унаследованный от Exception. Использоваться он будет примерно так:
L>L> try
L> {
L> .....
L> }
L> catch(SqlException sex)
L> {
L> SMSADVException ex2 = new SMSADVException(sex);
L> Common.WriteErrorInfo(ex2);
L> if (sqt != null)
L> sqt.Rollback();
L> }
L> public void WriteErrorInfo(Exception ex)
L> {
L> if (ex is SMSADVException)
L> {
L> ...
L> }
L> }
L>
L>Соответственно, в конструкторе надо скопировать все интересные мне поля из переданного параметра. Как это будет лучше всего сделать?
Я бы сделал так:
public void WriteErrorInfo(Exception ex)
{
// Этот WriteErrorInfo пишет куда? Во Writer какой-нибудь?
if (ex is ISMSADVException) {
((ISMSADVException)ex).Write(WriteErrorInfoInternalWriter);
} else {
// другие исключения
}
}
То есть все мои исключения реализуют некий интерфейс ISMSADVException, где определён метод Write, который умеет писать всё о себе в предоставленный ему Writer. Реальный Writer держится в Common.
Но, с другой стороны я бы вообще не стал держать это WriteErrorInfo в каком-то внешнем классе Common. Исключение — это сигнал вызывающему методу о том, что что-то не склалось. Пусть вызывающий класс заботится о том, что делать с этим сигналом, а исключение само о себе записало в стандартный лог. Таким образом код будет выглядеть так:
class Caller {
public LetsDoSomething() {
Callee c = new Callee();
try {
c.DoSomething();
} catch (ISMSADVException sex) {
// Опа! что-то случилось
}
}
}
class Callee {
public DoSomething() {
try {
...
} catch (SqlException sex) {
if (sqt != null)
sqt.Rollback();
throw new SMSADVException(sex);
} finally {
...
}
}
}
class SMSADVException : ISMSADVException {
public SMSADVException(Exception ex) {
// Тут запоминаем внутреннее исключение
// и пишем в лог
// что-нибудь типа
Write(MySystemErrorLog.Instance);
}
private override Write(TextWriter writer) {
// ...
}
}