簡體   English   中英

靜態與非靜態方法

[英]Static vs. non-static method

假設您在非靜態類中有一些可以變為靜態的方法。
例如:

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

您是否看到將方法簽名更改為靜態有什么好處? 在上面的例子中:

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

即使有一些性能或內存增益,編譯器也不會在編譯時進行簡單的優化嗎?


編輯:我正在尋找的是將方法聲明為靜態的好處。 that this is the common practice. 這是常見做法。 我想了解它背后的邏輯。
當然,這種方法只是澄清我的意圖的一個例子。

根據定義, power是無狀態的,並且對任何封閉類沒有副作用,因此它應該被聲明為static

MSDN中的這篇文章介紹了非靜態與靜態的一些性能差異。 調用的速度比實例化和調用快四倍,但它確實只是在一個性能瓶頸的緊密循環中才有意義。

如果將方法聲明為static,則應該稍微提高性能,因為編譯器將發出call IL指令而不是callvirt

但就像其他人所說的那樣,無論如何它應該是靜態的,因為它與特定的實例無關

請注意,編譯器甚至不太可能代表您進行更改,因為它會更改方法的簽名。 因此,一些精心設計的反射(如果您使用任何反射)可能會停止工作,編譯器實際上無法判斷是否是這種情況。

您是否看到將方法簽名更改為靜態有什么好處?

三個好處:

  1. 使無狀態方法靜態有助於記錄和闡明其目的。 否則,人們傾向於擔心該方法所依賴的神秘狀態?

  2. 靜態方法可以從其他靜態代碼調用,因此可能更有用。

  3. 靜態方法調用比實例調用具有更少的運行時開銷。 編譯器不能自動進行轉換 - 一個原因是因為它會影響null的使用。 即使在方法中沒有使用實例狀態,也需要在空引用上調用方法以使用NullReferenceException失敗。

不訪問實例數據或調用實例方法的成員可以標記為static(在Visual Basic中為Shared)。 將方法標記為靜態后,編譯器將向這些成員發出非虛擬調用站點。 發出非虛擬調用站點將阻止在運行時檢查每個調用,以確保當前對象指針為非null。 這可以為性能敏感的代碼實現可測量的性能增益。 在某些情況下,無法訪問當前對象實例表示正確性問題。

對我來說,一個簡單的問題是“我是否必須實例化此對象才能調用此函數”。 在你的功能的情況下,我會說答案是否定的,所以它應該是靜態的。 這個方法似乎與您的對象無關,所以我再次投票靜態。

此方法應該是靜態的,因為它與您的類或類成員無關。 它只適用於此功能的輸入。

也許你可能需要在不創建該類的情況下調用它。 所以,如果它是靜態的,那就沒關系,但如果不是,你就不能在沒有該類的任何實例的情況下調用它。


靜態方法的優點:

不需要先創建對象。 該方法立即可用。

當您擁有不依賴於特定對象狀態的通用功能時,這是一件好事。 例如,查看來自java.util的Arrays類或Collections類。

靜態方法對工廠有利。 將您的需求作為參數傳遞,獲得一個全新的對象。 看來不是構造函數。

靜態方法的缺點:

您沒有對象實例,因此您只能訪問靜態成員和您自己的局部變量。 如果你想要一個實例,你可能必須自己創建它。

您可以創建子類,但靜態方法不能是抽象的,因此將實現與調用者分離起來更加困難。


(ps:我不認為編譯器會優化,如果它是靜態的,但不確定)

編譯器可能會考慮在“JIT”代碼時將其內聯,因為它很短,如果它這樣做,那么很可能能夠優化對未使用的this參數的任何引用。 但你不能依賴任何一個。

你仍然需要創建一個對象來調用它,除非你把它變成靜態的,如果你因為其他原因不需要它,那么它的開銷會更大。

我相信編譯器不會將其優化為靜態方法。 由於不必檢查指針以查看它是否在運行時為空,因此可以獲得性能提升。 查看FXCop規則以供參考。

我希望我們需要定義靜態和非靜態方法之間的區別。 在這里,我發布了幾行簡單的代碼來可視化概念差異。

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";
     }

 }

現在讓我們創建一個aspx頁面嘗試訪問類中定義的這兩個方法。

 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
     }
 }

謝謝,請發表評論。

最誠摯的問候,Pritom Nandy [孟加拉國]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM