2009-07-26 27 views
29

Angenommen, Sie haben eine Methode, die in einer nicht statischen Klasse statisch gemacht werden könnte.
Zum Beispiel:Statische und nicht statische Methode

private double power(double a, double b) 
    { 
     return (Math.Pow(a, b)); 
    } 

Sehen Sie einen Nutzen aus der Methodensignatur in statisch zu ändern? In dem obigen Beispiel:

private static double power(double a, double b) 
    { 
     return (Math.Pow(a, b)); 
    } 

Auch wenn es einige Performance oder Speicher Verstärkung ist, wäre nicht der Compiler tut es als eine einfache Optimierung in der Kompilierung?


Bearbeiten: Was ich suchen, sind die Vorteile durch die Erklärung der Methode als statisch. I wissen, dass dies die gängige Praxis ist. Ich würde gern die Logik dahinter verstehen.
Und natürlich ist diese Methode nur ein Beispiel, um meine Absicht zu verdeutlichen.

+0

@Everyone, ich weiß, das ist eine "alte" Frage in den Entwicklungsjahren, aber es ist noch heute relevant. Viele ** ausgezeichnete ** Antworten unten. Benötigen Sie tatsächliche Leistungszahlen für Ihr spezifisches Szenario? Schreiben Sie ein schnelles Programm, das die Methode oft aufruft (zwischen 'var start = DateTime.Now()' und 'var end = DateTime.Now()'), um eine verstrichene Zeit zu haben, die groß genug ist, um zu vergleichen. Führen Sie es ein paar Mal mit "statisch" und ein paar Mal ohne "statisch" aus und vergleichen Sie den Unterschied. Öffnen Sie vielleicht den TaskManager und beobachten Sie auch die Speichernutzung für jedes Szenario. –

+0

Nur zur Vollständigkeit, anstatt den Unterschied zwischen den beiden 'DateTime.Now()' zu vergleichen, verwenden Sie die ['StopWatch'-Klasse] (https://msdn.microsoft.com/en-us/library/system.diagnostics. Stoppuhr (v = vs.110) .aspx). BEARBEITEN - Warum? Es ist genauer und einfacher zu verwenden als der 'DateTime.Now()' Weg. –

Antwort

7

Beachten Sie, dass es höchst unwahrscheinlich ist, dass der Compiler diese Änderung in Ihrem Namen vornehmen kann, da er die Signatur der Methode ändert. Als Ergebnis kann eine sorgfältig ausgearbeitete Reflektion (wenn Sie welche verwenden) nicht mehr funktionieren und der Compiler kann wirklich nicht sagen, ob dies der Fall ist.

+0

Guter Punkt. Ich habe nicht darüber nachgedacht, Danke. – Elad

1

Diese Methode sollte statisch sein, da sie nicht mit Ihrer Klasse oder dem Mitglied von Klassen zusammenhängt. Es funktioniert nur mit den Eingängen zu dieser Funktion.

vielleicht müssen Sie es möglicherweise anrufen, ohne diese Klasse zu erstellen. Wenn es also statisch ist, ist es in Ordnung, aber wenn es nicht ist, kann man es ohne irgendeine Instanz dieser Klasse nicht nennen.


Vorteile einer statischen Methode:

Es gibt keine Notwendigkeit, zunächst ein Objekt zu erstellen. Die Methode ist sofort verfügbar.

Es ist eine gute, wenn Sie generische Funktionalität haben, die nicht vom Zustand eines bestimmten Objekts abhängt. Betrachten Sie beispielsweise die Array-Klasse oder die Collections-Klasse von java.util.

Statische Methoden können für Fabriken gut sein. Übergeben Sie Ihre Anforderungen als Parameter, erhalten Sie ein brandneues Objekt zurück. Kein Konstrukteur in Sicht.

Nachteile einer statischen Methode:

Sie haben nicht eine Objektinstanz, so dass Sie nur den Zugriff auf statische Elemente und eigene lokale Variablen haben. Wenn Sie eine Instanz möchten, müssen Sie sie wahrscheinlich selbst erstellen.

Sie können Unterklassen erstellen, aber eine statische Methode kann nicht abstrakt sein. Daher ist es schwieriger, die Implementierung von einem Aufrufer zu entkoppeln.


(ps: ich glaube nicht, Compiler optimiert wird, wenn es statisch oder nicht .. aber nicht sicher sein wird)

33

Wie definiert, power staatenlos ist und hat keine Nebenwirkungen auf jeder umgebenden Klasse so sollte es static erklärt werden.

Diese article von MSDN geht in einige der Leistungsunterschiede von nicht statischen im Vergleich zu statischen. Der Anruf ist ungefähr viermal schneller als das Instanziieren und Anrufen, aber es ist wirklich nur in einer engen Schleife von Bedeutung, die einen Leistungsengpass darstellt.

+0

Wo ist der Link? –

+0

@Niko: Geändert. Entschuldigung und danke. – jason

+0

+1 für die msdn-Verknüpfung. –

2

Eine einfache Frage zu entscheiden ist "Muss ich dieses Objekt instanziieren, nur um diese Funktion aufzurufen". Im Falle Ihrer Funktion würde ich sagen, die Antwort ist nein, also sollte es statisch sein. Diese Methode scheint nicht zu Ihrem Objekt zu gehören, also stimme ich noch einmal ab.

+0

@Cody C: Aber wie geht man die Frage "Soll ich dieses Objekt instanziieren, nur um diese Funktion aufzurufen?" Beantworten? – jason

+1

IMO es ist nur eine Frage von "Benötige ich ein Objekt mit Status, wenn ich diese Funktionalität verwenden möchte?" Wenn ich ein Objekt nur instanziiere, um eine einfache Funktion auszuführen, ist diese Antwort normalerweise nein. –

+1

Das betreffende Beispiel ist "privat", das würde in diesem Fall keine Berücksichtigung finden (es wäre nur, wenn es "öffentlich" wäre). Die einzige Überlegung in diesem Fall sind die Angelegenheiten, die sich auf die Leistung beziehen. – awe

8

Es sollte eine leichte Leistungsverbesserung auftreten, wenn Sie die Methode statisch deklarieren, da der Compiler eine call IL-Anweisung anstelle von callvirt ausgibt.

Aber wie die anderen gesagt, es trotzdem statisch sein sollte, da es nicht auf eine bestimmte Instanz

0

ich der Compiler diese Optimierung nicht in einer statischen Methode glauben zusammenhängt. Es gibt eine Leistungssteigerung, da der Zeiger nicht überprüft werden muss, um festzustellen, ob er zur Laufzeit null ist. Werfen Sie einen Blick auf die FXCop rule als Referenz.

1

Der Compiler wird wahrscheinlich erwägen, dies zu inline zu setzen, wenn es den Code "JITs", da es so kurz ist, und wenn es dies tut, dann wird wahrscheinlich in der Lage sein, jeden Verweis auf den ungenutzten Parameter zu optimieren. Aber darauf kann man sich nicht verlassen.

Sie müssen noch ein Objekt erstellen, um es aufzurufen, es sei denn, Sie machen es statisch, was einen viel größeren Overhead hat, wenn Sie es aus anderen Gründen nicht benötigen.

+0

Sie haben bereits das Objekt ('this') als Beispiel für eine' private' Methode. – awe

-5

Ich hoffe, wir müssen den Unterschied zwischen statischen und nicht-statischen Methode definieren. Hier poste ich einige einfache Codezeilen, um den konzeptionellen Unterschied zu visualisieren.

public class StaticVsNonStatic 
{ 
    public string NonStaticMethod() //non-static 
    { 

     return "I am the Non-Static Method"; 

    } 

    static public string StaticMethod() //static 
    { 

     return "I am Static Method"; 
    } 

} 

Jetzt erstellen Sie eine aspx-Seite versuchen, auf diese 2 Methoden zuzugreifen, die in der Klasse definiert sind.

public partial class StaticVsNonStatic_StaticVsNonWorkplace : System.Web.UI.Page 
{ 
    protected void Page_Load(object sender, EventArgs e) 
    { 

     StaticVsNonStatic objStaticVsNonStatic = new StaticVsNonStatic(); 
     lblDisplayNS.Text = objStaticVsNonStatic.NonStaticMethod(); //Non Static 
     lblDisplayS.Text = StaticVsNonStatic.StaticMethod(); //Static and called without object 
    } 
} 

Danke und bitte Sie Kommentare schreiben.

Mit besten Grüßen, Pritom Nandy [Bangladesh]

+2

Elad weiß schon, wie man eine statische Methode nennt. Da Sie gerade anfangen, Fragen auf dieser Seite zu beantworten, würde ich vorschlagen, nach Fragen zu suchen, die noch keine akzeptierte Antwort haben. Sie können feststellen, dass bei der Suche nach Fragen die Anzahl der Antworten gelb ist, wenn eine Antwort akzeptiert wird, und Weiß, wenn nicht. Es gibt einen roten Hintergrund, wenn noch niemand versucht hat, die Frage zu beantworten, welche die besten sind. Willkommen bei stackoverflow :) –

2

Mitglieder, die als statisch markiert werden (Shared in Visual Basic) keine Instanzdaten zugreifen oder Instanzmethoden aufrufen können. Nachdem Sie die Methoden als statisch markiert haben, gibt der Compiler nicht virtuelle Aufruf-Sites an diese Member aus. Das Ausgeben nicht virtueller Aufruf-Sites verhindert eine Überprüfung zur Laufzeit für jeden Aufruf, der sicherstellt, dass der aktuelle Objektzeiger nicht null ist. Dies kann einen messbaren Leistungsgewinn für leistungsempfindlichen Code erzielen. In einigen Fällen stellt das Fehlschlagen des Zugriffs auf die aktuelle Objektinstanz ein Korrektheitsproblem dar.

3

Sehen Sie einen Vorteil darin, die Methodensignatur in eine statische zu ändern?

Drei Vorteile:

  1. staatenlos Methoden statisch hilft Dokument zu machen und ihren Zweck zu klären. Ansonsten ist man geneigt, sich zu fragen, welchen mysteriösen Zustand die Methode eigentlich braucht.

  2. Die statische Methode kann von anderem statischen Code aufgerufen werden, ist also möglicherweise nützlicher.

  3. Statische Methodenaufrufe haben einen kleineren Overhead als die Instanzmethoden. Der Compiler kann diese Transformation nicht automatisch durchführen - ein Grund dafür ist, dass dies die Verwendung von null beeinträchtigen würde.Der Aufruf der Methode für eine Nullreferenz muss mit einer NullReferenceException fehlschlagen, auch wenn in der Methode kein Instanzstatus verwendet wird.

Verwandte Themen