2012-03-04 111 views
2

我對static + const成員和static類兩個問題。靜態的常量成員,靜態類和瓶頸

一:爲什麼你會聲明一個擁有所有靜態和常量成員而不是靜態類的類?

我一直在研究.net代碼反射器作爲學習練習。我一直在研究的課程證明這個設計是FormsAuthentication課程。它的所有成員都標記爲staticconst,但它自己的類標記爲public sealed類中唯一的非靜態成員是沒有實現的默認構造方法。爲什麼這個班級沒有被標記爲public static sealed

我的第二個問題是關於爲什麼在FormsAuthentication類成員被聲明爲static。據我瞭解,應用程序的AppDomain中可能會有多個HttpApplications,並且所有這些HttpApplications將共享類的靜態成員。

二:這不會造成瓶頸嗎?如果是這樣,爲什麼它是這樣設計的?

回答

4

原因是FormsAuthentication是一個先於靜態類功能的類。它是在.NET 1.1中引入的,它沒有靜態類的概念。由於班級正在工作,現在沒有改變它的好處,所以很可能沒有人會重新考慮刪除私人空間,並將其變爲靜態而不是密封。

它可能是靜態的,因爲認證可以被認爲是單例。在你的應用程序中你不需要多於一個FormsAuthentication實例(雖然從技術上講,使用靜態類從來沒有一個實例,但是使用FormsAuth可能會有一個,你必須反編譯才能看到)。由於不需要創建多個實例,靜態方法就足夠了。它確實使單元測試代碼更加困難,但當時沒有考慮到單元測試。您不能將靜態類的實例傳遞給方法,而使用單例可以。

唯一的瓶頸是,有可能鎖定在幕後,作爲淨通常爲靜態成員線程安全。實際上,雖然這不太可能導致問題,它也可能有線程本地存儲,所以它可能根本不會進行任何鎖定。你必須反編譯才能確定。

這取決於是否存在必須鎖定以確保線程安全的靜態數據。如果存在,鎖定會導致共享資源的爭用,因爲線程將等待關鍵部分解鎖,即使只有一個線程被允許進入,其他線程也會等待。但是你也可以有靜態方法,它只使用來自參數或線程本地存儲變量的信息,在這種情況下,不涉及同步問題,並且可以獨立調用這些方法而不會造成瓶頸。

+0

那裏*是沒有實例化的'FormsAuthentication'實例。它是一個純粹的靜態類,正如你所指出的那樣,如果它沒有超過語法,就會在類上使用'static'關鍵字。因此,從單一意義上來考慮這個類是完全不準確的,這個單例本身就是一個*實例*。 – 2012-03-04 03:00:21

+1

@KirkWoll番茄,塔瑪託。在概念上它是同樣的事實,它的靜態方法與傳統的單例相比只是一個實現細節。當然,單身模式可以有一些優點,但是如果你不需要它們,靜態也可以很好地工作。 – Andy 2012-03-04 03:08:01

+1

這不是「實施細節」;一個由* definition定義的「singleton」需要一個* instance * - 這就是爲什麼它被稱爲單例。即「單一」實例。 – 2012-03-04 03:16:59