Mit Bedingungsoperator (?:) operator-Methode für Auswahl in C# (3.0)?
Ich bin refactoring von code.
Jetzt gibt es durchaus ein paar Orte, mit Funktionen wie diese:
string error;
if (a) {
error = f1(a, long, parameter, list);
}
else {
error = f2(the_same, long, parameter, list);
}
bevor refactoring f1 und f2 (die sind groß, aber ähnliche Dinge tun), würde ich gerne umgestalten zu:
string error = (a ? f1 : f2)(a, long, parameter, list);
Als würde man in C. (ist Die Funktion Signaturen sind identisch)
Aber ich bekomme eine Fehlermeldung:
"Fehler 13 Typ des bedingten Ausdrucks kann nicht bestimmt werden, denn es gibt keine implizite Konvertierung zwischen "Methode-Gruppe' und 'Methode-Gruppe'"
Dies würde mir erlauben, zu erkennen, dass die parameter-Listen identisch sind, die durch die Initiale refactoring geben invariant Verhalten, und auch umgestalten, die Aufrufe in einer einzigen Ort, der sicherstellt, dass alle in diesen verschiedenen refactorings, nichts kaputt, wie ich die Aufruf-Schnittstelle für die Methode.
Bin ich etwas fehlt klein, die es erlauben würde, eine syntax in der Nähe dieser arbeiten (im Gegensatz zu einer ganzen Reihe von zusätzlichen Delegaten-Typ-Definitionen etc)?
Sorry, zu Bearbeiten, aber es gibt tatsächlich einen Wert zurück, und ja, leider ist es ein string. ;-(
Gerade jetzt, ich bin für die Beilegung dieses:
string error = a ? f1(a, long, parameter, list) : f2(a, long, parameter, list);
Das problem ist, dass die parameter-Liste sind in der Tat sehr lange, und gehen zu bekommen, umgestaltet, und ich würde lieber haben Sie konsolidiert erste und befassen sich mit der compiler-Fehler, da ich diese ändern.
- (gelöscht, all die Kommentare über operator benennen; eine Seite Thema am besten)
Du musst angemeldet sein, um einen Kommentar abzugeben.
Können Sie tun, dass durch die Deklaration einer delegate, als Sie darauf hingewiesen.
Merke ich, dass Sie schrieb, dass Sie tun dies in ganz wenigen Orten. Eine weitere alternative, die vielleicht besser geeignet ist die Verwendung von Schnittstellen. Instanziieren eines von zwei verschiedenen Arten je nach dem Wert von a, dann rufen Sie die Methode auf das Objekt.
Wenn Sie mehrere Methoden, die sich ändern müssen gleichzeitig abhängig vom Wert des
a
dann können Sie Sie alle in der gleichen Schnittstelle und Sie brauchen nur zu prüfena
einmal.Für die
?
zu arbeiten, muss der compiler einen expliziten Typ für mindestens einen der Operanden. Sie können hier über einen cast-operatorErsetzen
T*
mit den tatsächlichen Typen des delegate-ParameterMüssen Sie instanziieren Sie eine der Methoden, wie eine bestimmte kompatibel Stellvertretung Art. Es gibt einfach keine Möglichkeit um ihn herum. Das wird, leider, ein wenig Ausführlicher ist, als du suchst:
Du gehst zu haben, um die beteiligten Parameter explizit, sei es, dass durch die Verwendung eines
Action
(oderFunc
) generische überladung, passt oder deklarieren Ihre eigenen Delegierten geben.Dieser kommt auf die Art der Auflösung. Angesichts der Ausdruck:
Der compiler sieht nicht für die gemeinsame Belegung-kompatibel Vorfahren für
tVal
undfVal
(und selbst wenn es das täte, die Litanei von verschiedenen Delegat-Typen, für die jeder könnte gültig sein könnte riesige); wenn es nicht die Zuordnung der Kompatibilität zwischen den Typen dertVal
undfVal
in beide Richtungen, der compiler macht Sie explizit, was Sie wollen.Für was es Wert ist, sollten Sie sich bewusst sein, dass unter diesem Ansatz weisen Sie einen neuen Delegaten entweder
f1
oderf2
jedes mal, wenn diese Methode aufgerufen wird, dann, dass der Delegat aufgerufen wird, dann verworfen. Ich erwähne dies nur, weil Delegat Aufruf ist langsamer als gewöhnliche früh-gebundenen (oder auch virtuelle) Methode invocation. Es kann auch nicht ein Rücksicht und Kompromiss könnte es Wert sein, aber es ist noch Wert wissen.Wenn Sie einen Delegaten-Typ, es wird Ihnen erlauben, zu tun, was Sie Fragen:
Mit den Erklärungen:
Getestet .Net 4, aber sollte für die Anwendung .Net 3.5
Nein, im Grunde genommen, ohne dass es weniger effizient. Wenn es einen Rückgabewert, die Sie verwenden können:
aber das ist über es.
Gut, Sie kann erstellen Sie ein paar von den Delegierten der Methode Gruppe, aber das erhöht den Verarbeitungsaufwand für keinen guten Grund. Ich werde nicht unterstützen.
Ich würde denken, dass etwas wie die folgenden besser funktionieren würde:
einen ? f1(a, long parameter list) : f2(a, long parameter list);
Besetzung das Ergebnis des ternären einer
Action