Как установить InnerException пользовательского Класса исключений от его конструктора

GUID, по определению, уникальны во всех отношениях. Были, когда-то давно, некоторые стандартные программы GUID0-поколения, которые генерировали последовательные GUID, но те были проблемами в... Win98, я думаю и был hotfixed Microsoft.

Вам необходимо доверять сгенерированному GUID, чтобы быть уникальными и никогда не повторяли или повторно создавали.

(РЕДАКТИРОВАНИЕ: Однако все мы понимаем, что строка алфавитно-цифровых символов имеет постоянное число перестановок, если строка починена в длине. Но в случае GUID количество перестановок является economical*.)

(* Черт возьми, где то, что XKCD, где предложение "астрономических" чисел не являются достаточно большими?)

43
задан Shekhar 5 November 2019 в 18:18
поделиться

7 ответов

Почему нельзя просто вызвать конструктор, взяв InnerException в качестве параметра? Если по какой-то причине это невозможно, поддерживающее поле в System.Exception:

private Exception _innerException;

Я обнаружил это с помощью Reflector Redgate . Используя отражение, я полагаю, вы могли бы установить внутреннее исключение.

Edit: В большинстве случаев не рекомендуется получать доступ к закрытым полям через отражение, но я недостаточно знаю о случае NT, чтобы точно знать, если это хорошая или плохая идея.

13
ответ дан 26 November 2019 в 22:26
поделиться

Вы устанавливаете внутреннее исключение, вызывая базовый 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) {...}
83
ответ дан 26 November 2019 в 22:26
поделиться

Класс Exception имеет перегруженный конструктор, принимающий внутреннее исключение в качестве параметра:

Exception exc = new Exception("message", new Exception("inner message"));

Это то, что вы ищете?

40
ответ дан 26 November 2019 в 22:26
поделиться
Exception exceptionWithMoreInfo = new Exception("extra info", ex);

было бы нормальной практикой, если бы вы перехватили исключение, для которого вы хотите добавить дополнительную информацию, прежде чем всплыть.

8
ответ дан 26 November 2019 в 22:26
поделиться

Если я понимаю ваш вопрос, вы хотите сделать что-то вроде этого:

Exception ex = new Exception("test");
Exception innerEx = new Exception("inner");
ex.GetType().GetField("_innerException", BindingFlags.NonPublic | BindingFlags.Instance).SetValue(ex, innerEx);

Если вы находитесь в конструкторе объекта, который наследуется от Exception, вы должны использовать this вместо из первого ex .

Но, возможно, это не лучший способ справиться с тем, с чем вы пытаетесь справиться.

2
ответ дан 26 November 2019 в 22:26
поделиться

Разве InnerException не должно быть установлено при использовании конструктора Exception (string, Exception) ? Я думаю, что вы не можете изменить это по умолчанию, но вы всегда можете обратиться к соответствующему конструктору во время создания:

class MyException : Exception {
    public MyException()
        : base("foo", new Exception("bar"))
    {
        ...
    }

    ...
}

Я думаю, вы никогда не должны нарушать цепочку исключений в своем коде, поскольку это обычно приводит к ошибкам, которые вы больше никогда не найду.

1
ответ дан 26 November 2019 в 22:26
поделиться

Используйте Отражатель Редгейта, чтобы найти поле. Я сомневаюсь, что реализация Exception когда-нибудь изменится ... Но это риск!

1
ответ дан 26 November 2019 в 22:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: