Ich möchte ein MethodInfo
-Objekt dynamisch aufrufen, und alle Ausnahmen, die von innen heraus geworfen werden, gehen nach außen, als ob es normal aufgerufen würde.
Ich habe zwei Möglichkeiten, scheint es. Sie sind unten umrissen.
Option 1 behält den Typ der Ausnahme bei, die von MyStaticFunction
ausgelöst wurde, aber StackTrace
ist wegen throw
ruiniert.
Option 2 behält die StackTrace
der Ausnahme bei, aber der Typ der Ausnahme ist immer TargetInvocationException
. Ich kann das InnerException
und seinen Typ herausziehen, aber das bedeutet, dass ich das zum Beispiel nicht schreiben kann:
Option 1:
%Vor%Option 2:
%Vor% Was ich wirklich will ist, dass Anrufer DoDynamicCall
Ausnahmen so erhalten, als hätten sie Folgendes aufgerufen:
Gibt es eine Möglichkeit, die Vorteile von Option 1 und Option 2 zu nutzen?
Die Option, die ich gerne hätte (erfundenes neues C # -Schlüsselwort rethrow
vor Ort):
Dies würde auch die Notwendigkeit für diesen Spinner beseitigen, weil Sie stattdessen rethrow e;
verwenden könnten:
Im Allgemeinen wäre es eine Möglichkeit, throw;
von der Anforderung "Ich muss direkt in einem Catch-Block sein" zu entkoppeln.
Hier ist die Lösung, die ich mir ausgedacht habe. Es erledigt die Arbeit. Ich bin immer noch an anderen Antworten interessiert, da es etwas einfacheres oder saubereres geben könnte.
throw;
die Ausnahme, die Sie weitergeben möchten, nicht die Ausnahme des aktuellen catch
Blocks ist, verwenden Sie throw Functional.Rethrow(e);
try...catch...
durch Functional.TryCatch
try...catch...finally...
durch Functional.TryCatchFinally
Hier ist der Code:
%Vor% In .NET 4.5 gibt es die neue System.Runtime.ExceptionServices.ExceptionDispatchInfo
class . Dies kann verwendet werden, um eine Ausnahme zu erfassen:
Und später wird dies verwendet, um das Auslösen der Ausnahme fortzusetzen:
%Vor% Nein, ich glaube nicht, dass es einen Weg gibt, die Vorteile beider zu nutzen. Wenn Sie jedoch e.InnerException
werfen, können Sie weiterhin den ursprünglichen StackTrace abrufen, da Sie einfach e.InnerException.StackTrace
verwenden können, um den ursprünglichen Stack-Trace zu erhalten. Kurz gesagt, sollten Sie Option 1 verwenden.
Die beste Option ist Option 3 : Verwenden Sie keine Reflektion, sondern verwenden Sie Expression<T>.Compile()
.
Anstatt dies zu tun:
%Vor%Versuchen Sie, dies anzustreben:
%Vor%Der Vorbehalt ist, dass Sie die Methodensignatur kennen müssen, obwohl Sie Code schreiben können, der den Ausdruck dynamisch so erstellt, dass er in eine von mehreren Signaturen passt.
Sie können diese Technik vielleicht nicht immer anwenden, aber wenn Sie es tun, ist es die beste Option. Für alle Absichten und Zwecke ist es wie ein anderer Delegierter zu nennen. Es ist auch schneller als die Reflektion, wenn Sie mehrere Aufrufe vornehmen (in diesem Fall kompilieren Sie nur einmal und behalten Sie den kompilierten Delegierten im Griff).
Tags und Links c# reflection exception