Как я могу установить InnerException
свойство Exception
объект, в то время как я нахожусь в конструкторе того объекта? Это сводится к нахождению и установке отступающего поля свойства, которое не имеет никакого метода set.
BTW: Я видел этот evain.net - Получение поля, поддерживающего свойство с помощью Отражения, но ища не основанное на IL решение, если это возможно.
Конструктор Exception
место где Exception
тип создается, таким образом, я не могу назвать его с помощью конструктора базового класса MyException() :base(...)
и т.д.
Почему нельзя просто вызвать конструктор, взяв InnerException в качестве параметра? Если по какой-то причине это невозможно, поддерживающее поле в System.Exception:
private Exception _innerException;
Я обнаружил это с помощью Reflector Redgate . Используя отражение, я полагаю, вы могли бы установить внутреннее исключение.
Edit: В большинстве случаев не рекомендуется получать доступ к закрытым полям через отражение, но я недостаточно знаю о случае NT, чтобы точно знать, если это хорошая или плохая идея.
Вы устанавливаете внутреннее исключение, вызывая базовый ctor:
public MyException(string message, Exception innerException)
: base(message, innerException) {...}
Если вам нужно запустить некоторый код для получения исключения, используйте статический метод:
public MyException(SomeData data) : base(GetMessage(data), GetInner(data)) {...}
static Exception GetInner(SomeData data) {...} // <===== your type creation here!
static string GetMessage(SomeData data) {...}
Класс Exception
имеет перегруженный конструктор, принимающий внутреннее исключение в качестве параметра:
Exception exc = new Exception("message", new Exception("inner message"));
Это то, что вы ищете?
Exception exceptionWithMoreInfo = new Exception("extra info", ex);
было бы нормальной практикой, если бы вы перехватили исключение, для которого вы хотите добавить дополнительную информацию, прежде чем всплыть.
Если я понимаю ваш вопрос, вы хотите сделать что-то вроде этого:
Exception ex = new Exception("test");
Exception innerEx = new Exception("inner");
ex.GetType().GetField("_innerException", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(ex, innerEx);
Если вы находитесь в конструкторе объекта, который наследуется от Exception, вы должны использовать this
вместо из первого ex
.
Но, возможно, это не лучший способ справиться с тем, с чем вы пытаетесь справиться.
Разве InnerException
не должно быть установлено при использовании конструктора Exception (string, Exception)
? Я думаю, что вы не можете изменить это по умолчанию, но вы всегда можете обратиться к соответствующему конструктору во время создания:
class MyException : Exception {
public MyException()
: base("foo", new Exception("bar"))
{
...
}
...
}
Я думаю, вы никогда не должны нарушать цепочку исключений в своем коде, поскольку это обычно приводит к ошибкам, которые вы больше никогда не найду.
Используйте Отражатель Редгейта, чтобы найти поле. Я сомневаюсь, что реализация Exception когда-нибудь изменится ... Но это риск!