2017-12-25 46 views
1

Zum Beispiel habe ich eine Klasse mit einer void Methode darin.Was ist der Unterschied zwischen diesen beiden Methodenaufrufen in C#?

Das ist meine Klasse:

class MyClassTest 
{ 
    public void Print() 
    { 
     Console.WriteLine("Hello"); 
    } 
} 

Ich bin neu in Klassen und wenig verwirrt, gibt es einen Unterschied zwischen diesen beiden Methodenaufrufe?

Hier ist meine Hauptmethode

static void Main(string[] args) 
{ 
    //first call 
    MyClassTest ms = new MyClassTest(); 
    ms.Print(); 

    //second call 
    new MyClassTest().Print(); 
} 
+3

Kurz gesagt, kein Unterschied. – JohnyL

+0

@JohnyL welchen Weg soll ich mehr nutzen? –

+0

@RonJeremy sagen Sie möchten mehrere Methoden der gleichen Instanz aufrufen..wird der zweite Anruf noch eine Option sein? Es geht darum, dieselbe Instanz wiederzuverwenden. –

Antwort

5

Im Fall unterhalb Sie dies tun werden soll, wenn Sie einen Verweis auf das konstruierte Objekt behalten möchten und einige weitere Operationen mit ihm später auszuführen.

MyClassTest ms = new MyClassTest(); 
ms.Print(); 

Während im Fall unterhalb Sie nur dies tun wollen, wenn Sie nicht mehr über die konstruiertes Objekt nach dem Bau kümmern, sondern sind nur daran interessiert, die Methode Print aufrufen.

new MyClassTest().Print(); 

Der feine Unterschied zwischen diesen beiden Szenarien ist, dass in dem Fall, in den das Objekt verwiesen wird, weitere Operationen durchführt wird es wahrscheinlich später als ein Objekt zerstört werden, die nicht mehr das heißt das zweite Beispiel verwiesen wird oben als GC (Garbage Collector) wird herausfinden, dass es keine Referenzen hat und beschließt daher, es loszuwerden.

+3

Ich würde weiter kommen und sagen, dass wenn du die zweite oft tust, du höchstwahrscheinlich etwas falsch machst. Verwenden Sie statische Methoden, wenn Sie die Insassen nicht interessieren –

+0

In beiden Fällen kann das Objekt unmittelbar nach dem Aufruf zum Drucken gesammelt werden (außer, wenn Sie unter Debugger laufen, wo Variable möglicherweise länger leben, so dass Sie ihren Wert überprüfen können). – Evk

+0

@Evk In Ordnung, aber im Allgemeinen Objekte, die immer noch Referenzen haben, sind am wahrscheinlichsten_ zu Garbage Collection später als die ohne und auch die Zeit, zu der Objekte Müll gesammelt werden, ist _non-deterministic_. –

0

Ihre beiden Aufrufe führen dieselbe semantische Operation in C# aus: Der Unterschied besteht darin, dass Sie beim ersten Aufruf die Variable ms erstellen, die dem Leser vorschlägt, dass er sie in Ihrem Code erneut verwenden soll: Sie sind es tatsächlich Rufen Sie ms.Print() nach.

Ihr zweiter Aufruf, deklariert keine Variable, das bedeutet, dass Ihre Absicht ist, die Print-Methode auf einer brandneuen MyClassTest Instanz nur einmal in Ihrem Code aufzurufen, und Sie kümmern sich nicht um die gerade erstellte Instanz .

Hinweis: Wenn Sie im Freigabemodus kompilieren, wird der C# -Compiler die variable Nutzung komprimieren und reduzieren, daher werden Ihre beiden Aufrufe die gleiche kompilieren und sie werden wie Ihr zweiter Aufruf sein.

+0

vielen Dank für die nette Erklärung, über diesen Release-Modus, wird 'ms' Variable (Obj) für einige weitere Eigenschaften die Dinge anders machen? –

+1

Gern geschehen. Die Verwendung von 'ms' für zusätzliche" Dinge "ändert den kompilierten Code. Die genaue Ausgabe hängt jedoch von vielen Faktoren ab, die im aktuellen Kontext schwer abzuschätzen sind. – pier

2

Es gibt keinen Unterschied, eigentlich. Sie verwenden den ersten Fall, wenn Sie in Ihrem Programm weiter auf MyTestClass verweisen müssen. Sie verwenden den zweiten Fall als fire-and-forget. Wenn Sie planen, den zweiten Fall stark zu verwenden, wird empfohlen, die Methode Print als static zu verwenden.

Der IL-Code zeigt keinen Unterschied, außer WithInstance Methode, wenn variable Halte Bezugnahme auf den Stapel geladen wird (stloc.0 und ldloc.0 IL Anweisungen):

MyClassTest ms = new MyClassTest(); 
ms.Print(); 

Image1

new MyClassTest().Print(); 

Image2

+0

Führt der zweite oder statische Aufruf dieser Methode zu weniger Speicherplatz im Speicher, weil es keine Variablenhalte-Referenz gibt? –

+0

Die zweite Methode reserviert sowohl Speicher als auch zuerst. Wie bei der statischen Methode sollten Sie entweder die statische Klasse oder die reguläre Klasse mit der statischen Methode verwenden. – JohnyL

0

In diesem speziellen Fall, nein.

Jedes Mal, wenn Sie eine Methode für ein Ergebnis eines anderen Methodenaufrufs aufrufen, new, Zugriff auf Eigenschaften usw.

var temp = new MyClassTest() 
temp.Print(); 

Also in diesem Fall Ihre zwei Beispiele sind die gleichen: Stand: wenn Sie taten

new MyClassTest().Print(); 

Es zu ähnlich ist.

Es gibt einige Varianten, in denen sie sich unterscheiden.

Es wären Objekte vom Werttyp, auf die über Array- oder Feldzugriff zugegriffen wird. Hier kann der Zugriff die Adresse des tatsächlichen Objekts verwenden, anstatt eine Kopie zu erstellen. Nun ist es möglich, dass das Gegenteil passiert, wo anstelle eines impliziten temporären lokalen Seins erstellt und explizite lokale entfernt wird, aber es wird nicht versprochen. Beachten Sie, dass bei änderbaren Werttypen der Code mit und ohne temporärem Local für diese Fälle auch nicht semantisch gleich ist (sondern für einen Fall, der näher an Ihrem Beispiel liegt, wo das Objekt das Ergebnis eines Methodenaufrufs ist, der kein a war ref return zu einer ref Variable).

Eine andere ist, wenn es in einer yield-using oder async Methode ist. Hier werden die Locals in Ihrer Methode zu Feldern in einem erzeugten Objekt (das entweder IEnumerable<T> und/oder IEnumerator<T> für yield oder Task für async implementiert), während die "unsichtbaren" temporären Locals, die ich oben beschrieben habe, dies nicht tun. (Der Compiler könnte und wird wahrscheinlich in der Zukunft einen besseren Job machen, um einige davon loszuwerden, die nach yield oder async Calls nicht existieren und deshalb nicht wirklich Felder sein müssen, aber vorerst alles die Einheimischen werden Felder).

So gibt es ein paar Mal, wenn explizite Locals mit einer einzigen Operation auf sie etwas anders als die Operation direkt auf die Mittel, mit denen Sie den Wert erhalten haben, obwohl Ihr Beispiel ist nicht einer dieser Zeiten.

Verwandte Themen