GUID, по определению, уникальны во всех отношениях. Были, когда-то давно, некоторые стандартные программы GUID0-поколения, которые генерировали последовательные GUID, но те были проблемами в... Win98, я думаю и был hotfixed Microsoft.
Вам необходимо доверять сгенерированному GUID, чтобы быть уникальными и никогда не повторяли или повторно создавали.
(РЕДАКТИРОВАНИЕ: Однако все мы понимаем, что строка алфавитно-цифровых символов имеет постоянное число перестановок, если строка починена в длине. Но в случае GUID количество перестановок является economical*.)
(* Черт возьми, где то, что XKCD, где предложение "астрономических" чисел не являются достаточно большими?)
Почему нельзя просто вызвать конструктор, взяв 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 когда-нибудь изменится ... Но это риск!