2009-02-26 10 views
3

Gibt es Kosten in Verbindung mit Überlademethoden in .Net?Methode überladene Kosten in .Net

Also, wenn ich drei Methoden wie:

Calculate (int) 
Calculate (float) 
Calculate (double) 

und diese Methoden werden zur Laufzeit „dynamisch“ genannt basiert auf, was auf die Calculate-Methode übergeben wird, was die Kosten für diese Überladungsauflösung wäre?

Alternativ könnte ich eine einzige Calculate haben und den Unterschied in der Methode body machen, aber ich dachte, dass würde die Methode erfordern, um den Typ jedes Mal zu bewerten, wenn es aufgerufen wird.

Gibt es bessere Möglichkeiten/Designs, um dies zu lösen, mit vielleicht keinen Overhead? Oder noch besser: Was ist die beste Vorgehensweise, um solche Fälle zu behandeln? Ich möchte denselben Klassen-/Methodennamen, aber ein anderes Verhalten haben.

EDIT: Danke allen. Irgendwas wenn es anders ist. Ich frage mich, ob Sie eine DLL für diese Methoden und ein in C# geschriebenes Programm haben, das dem Benutzer erlaubt, diese Methoden als UI-Elemente hinzuzufügen (ohne den Typ anzugeben). Also fügt der Benutzer das UI-Element Calculate (5) und dann Calculate (12.5) usw. hinzu, und die C# -App führt dies aus, würde es noch keinen Overhead geben?

+0

Diese Frage bezieht sich auf Methodenüberladung, die sich von Polymorphie völlig unterscheidet. –

+0

@Cris: .NET Pro-Anweisung Kosten ist praktisch nichts, am häufigsten ist die Framework-Ladezeit ein Problem (~ 500ms jetzt?) –

+0

yeah ... du wirst in Überladungen im Vergleich zu Überschreibungen – wowest

Antwort

15

Soweit es die Laufzeit betrifft, sind dies verschiedene Methoden. Ist das gleiche wie das Schreiben:

CalculateInt(int) 
CalculateFloat(float) 

In Bezug auf die Performance-Probleme, außer sehr besonderen Fällen Sie sicher den Methodenaufruf Kopf ignorieren können.

+0

One-Way zu suchen um dies zu optimieren wäre es, Generika zu verwenden. –

+0

@John: Sie meinen für meine 3 Calculate Methode Fall? –

+0

@Aleris: Was für Sonderfälle? – NotMe

1

3 verschiedene Methoden werden in IL basierend auf dem Typ hergestellt. Die einzigen Kosten entstehen, wenn Sie von einem Typ in einen anderen umwandeln, aber diese Kosten sind nicht signifikant, es sei denn, Sie haben eine große Menge zu tun. Sie könnten also bei Calculate (double) bleiben und von dort aus casten.

7

Erstens, es sei denn, Ihr Profiler sagt Ihnen, dass es ein Performance-Problem gibt, sollten Sie kein gutes Design für angenommene Leistungssteigerungen opfern.

Um Ihre Frage zu beantworten, ist die Auflösung von Methodenaufrufen nicht dynamisch. Es wird zum Zeitpunkt der Kompilierung festgelegt, es entstehen also keine Kosten. Die einzigen Kosten wären die mögliche implizite Umwandlung eines Typs in den Parametertyp.

9

Diese Frage bezieht sich auf Methodenüberladung, nicht auf Polymorphie. Soweit ich weiß, gibt es keine Strafe für das Überladen von Methoden, da der Compiler herausfinden wird, welche Methode zur Kompilierzeit aufgerufen wird, basierend auf dem Typ des Arguments, das an ihn übergeben wird.

Polymorphie kommt nur dann zum Einsatz, wenn Sie einen abgeleiteten Typ als Ersatz für eine Basisklasse verwenden.

+0

Vielen Dank für das Aufzeigen der offensichtlichen (nicht sarkastisch, ich upvoted). Es besteht ein signifikanter Unterschied zwischen Überladung und Polymorphie. –

4

Die Methodenüberladung (d. H. Der Tabellenslot der Methode) wird zur Laufzeit nicht dynamisch aufgelöst, sie wird zur Kompilierungszeit statisch aufgelöst, sodass es keine Kosten für überladene Methoden gibt.

Ich nehme an, Sie denken an virtual Methoden, bei denen die tatsächliche Implementierung von einem abgeleiteten Typ überschrieben werden kann und die tatsächliche Methode basierend auf dem konkreten Typ ausgewählt. Aber das hat nichts mit Überladung zu tun, da virtuelle Methoden den gleichen Methoden-Tabellen-Slot belegen.

2

Es gibt keine "Kosten" zur Laufzeit, da der Compiler bestimmt, welche Methode zur Kompilierzeit aufgerufen wird.Die IL, die generiert wird, ruft die Methode auf, die die entsprechenden Parameter verwendet.

Nimm dies zum Beispiel i "“

public class Calculator 
{ 
    public void Calculate(int value) 
    { 
     //Do Something 
    } 
    public void Calculate(decimal value) 
    { 
     //Do Something 
    } 
    public void Calculate(double value) 
    { 
     //Do Something 
    } 
} 

static void Main(string[] args) 
{ 
    int i = 0; 
    Calculator calculator = new Calculator(); 
    calculator.Calculate(i); 
} 

der folgende Aufruf in IL hergestellt wird die Variable zu berechnen":

L_000b: callvirt instance void ConsoleApplication1.Calculator::Calculate(int32) 

bemerkt, dass es das Verfahren spezifiziert vom Typ int32 ist, das ist Derselbe Typ wie die Variable, die von der Main-Methode übergeben wurde.

Wenn also überhaupt Kosten anfallen, dann nur zur Kompilierungszeit. Keine Sorge.

Wie JaredPar unten angegeben:

Es ist ein Irrglaube in Ihrer Frage. Überladene Methoden in C# sind , die zur Laufzeit nicht dynamisch aufgerufen werden. Alle Methodenaufrufe sind statisch unter Kompilierzeit gebunden. Daher gibt es keine "Suche" nach einer Methode zur Laufzeit, es ist zur Kompilierzeit vorbestimmt, welche Überladung aufgerufen wird.

1

Es gibt ein Missverständnis in Ihrer Frage. Überladene Methoden in C# werden zur Laufzeit nicht dynamisch aufgerufen. Alle Methodenaufrufe werden zur Kompilierungszeit statisch gebunden. Daher gibt es kein "Suchen" nach einer Methode zur Laufzeit, es ist zur Kompilierzeit vorbestimmt, welche Überladung aufgerufen wird.

Hinweis: Dies ändert sich ein wenig mit C# 4.0 und dynamisch. Bei einem dynamischen Objekt ist es möglich, dass zur Laufzeit eine Überladung basierend auf dem Typ des Objekts gewählt wird. Dies ist jedoch nicht bei C# 3.0 und darunter der Fall.

Verwandte Themen