2 Stimmen

Umstrukturierung, um Ausnahmen nicht zu verwenden, indem bestimmt wird, welche Methode implementiert wird

Ich entwickle also etwas, das auf dynamic Variablen mit C# 4. Und ich bin in einer Situation, in der ich zwei Variablen habe a y b und ich conozca die entweder a.Foo(b) o b.Foo(a) definiert ist. Allerdings weiß ich nicht, welche, so dass ich im Moment etwas wie dieses verwenden:

dynamic a, b, result;
...

try
{
    result = a.Foo(b);
}
catch
{
    result = b.Foo(a);
}

Das ist furchtbar (es ist nicht nur unelegant, sondern auch sehr langsam, da die Wahrscheinlichkeit, dass ein Fehler auftritt, etwa 0,5 beträgt). Exception und erzeugt einen Stack-Trace). Ich könnte Reflexion verwenden, aber ich erwarte, dass das auch ziemlich langsam sein würde.

Gibt es also einen besseren Weg?


Das ist also das Problem... aber ich werde auch den Kontext erklären, da ich denke, dass es eine gute Möglichkeit gibt, die ganze Situation besser zu handhaben. Im Wesentlichen baue ich Ausdruck Bäume (mit meiner eigenen Knotenstruktur), die mit vielen verschiedenen Datentypen arbeiten.

Wenn Sie den Ausdruck 1+'2' die a y b Werte sind die Operanden 1 y '2' . Wenn ich die + Knoten, der die Unterbäume a y b kann jeder Operand eine Methode enthalten, die Add den Typ des anderen Operanden zu. Das heißt, entweder a.Add(b) implementiert ist oder b.Add(a) umgesetzt wird.

Ich kann mir nur vorstellen, Reflexion zu verwenden, die obige Methode, oder doppelte Funktionen in beiden Arten von a y b um die Symmetrie zu modellieren.

1voto

Ed Altorfer Punkte 4344

Microsoft würde empfehlen, dass Sie dies tun, indem Sie eine IsImplemented Eigenschaft oder Methode, die Sie aufrufen können sollten, um festzustellen, welches Ihrer Objekte die Foo bevor er einen von ihnen anruft, um dann festzustellen, dass er es nicht tut.

Der Overhead der Ausnahmebehandlung ist nicht énorme Aber es ist spürbar, und Sie sollten Ausnahmen wirklich vermeiden, es sei denn, Sie behandeln ein außergewöhnliches Szenario. Dies ist ein wesentlicher Unterschied zwischen Ausnahmen und Fehlercodes aus C/C++.

Also, fügen Sie eine IsFooImplemented Eigenschaft oder etwas Ähnliches. Das erspart Ihnen eine Ausnahme.

0voto

Seth Punkte 42154

Wie wäre es mit der Umwandlung beide Operanden in eine richtige Zahl umwandeln, bevor man versucht, sie zu addieren?

D.h., verwenden Sie etwas wie System.Convert wie beschrieben aquí , dann:

dynamic a2 = DoConvertToInteger(a);
dynamic b2 = DoConvertToInteger(b);

result = a2 + b2;

0voto

GrayWizardx Punkte 17771

Ich denke (wie Ed gesagt hat), ich würde dies mit einer Schnittstelle (d.h. IResolve) lösen, die auf jeden der Knoten in Ihrer Hierarchie angewendet wird:

Interface IResolve {
   IResolve Resolve();
   object Value { get; }
   bool IsResolved { get; }
}

class Add : IResolve {
   List<IResolve> entities;

   protected IResolve doMyAddLogic(IResolve lvalue, IResolve rvalue) {
       return new ResolvedNodeValue(lvalue.Value + rvalue.Value);
   }

   public IResolve Resolve() {
      IResolve result = null;

      foreach(var child in entities) { 
         result = doMyAddLogic(result, child.Resolve());
      }

      return result;
   }
}

Das Problem ist, dass die Auflösung hinter einer Schnittstelle nicht eindeutig ist. Es ist nicht perfekt, und ich mag das Fehlen der formalen Sprache Notation (d.h. Determinismus des Baumes), aber es könnte ein Ort sein, um zu beginnen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X