Erhaltung von Ausnahmen von dynamisch aufgerufenen Methoden

8

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:

%Vor%

Option 1:

%Vor%

Option 2:

%Vor%

Was ich wirklich will ist, dass Anrufer DoDynamicCall Ausnahmen so erhalten, als hätten sie Folgendes aufgerufen:

%Vor%

Gibt es eine Möglichkeit, die Vorteile von Option 1 und Option 2 zu nutzen?

Bearbeiten:

Die Option, die ich gerne hätte (erfundenes neues C # -Schlüsselwort rethrow vor Ort):

%Vor%

Dies würde auch die Notwendigkeit für diesen Spinner beseitigen, weil Sie stattdessen rethrow e; verwenden könnten:

%Vor%

Im Allgemeinen wäre es eine Möglichkeit, throw; von der Anforderung "Ich muss direkt in einem Catch-Block sein" zu entkoppeln.

    
Timothy Shields 27.03.2013, 20:03
quelle

4 Antworten

6

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.

  • Wenn Sie möchten, dass die Funktionalität von throw; die Ausnahme, die Sie weitergeben möchten, nicht die Ausnahme des aktuellen catch Blocks ist, verwenden Sie throw Functional.Rethrow(e);
  • Ersetzen Sie try...catch... durch Functional.TryCatch
  • Ersetzen Sie try...catch...finally... durch Functional.TryCatchFinally

Hier ist der Code:

%Vor%

Aktualisieren

In .NET 4.5 gibt es die neue System.Runtime.ExceptionServices.ExceptionDispatchInfo class . Dies kann verwendet werden, um eine Ausnahme zu erfassen:

%Vor%

Und später wird dies verwendet, um das Auslösen der Ausnahme fortzusetzen:

%Vor%     
Timothy Shields 28.03.2013, 01:27
quelle
1

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.

    
feralin 27.03.2013 20:06
quelle
0

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).

    
Amir Abiri 29.04.2014 07:45
quelle
0

Ich hatte ein ähnliches Problem und kam auf folgendes:

%Vor%

Ein Beispiel für die Verwendung ist unten:

%Vor%     
Daryl 28.05.2014 14:48
quelle

Tags und Links