2012-04-13 69 views
11

我需要知道如何防止在.NET中實例化類。防止類被實例化的最佳方法?

我知道很少的方法,比如使類Abstract和Static。

有沒有更多的方法來實現這一目標?

+0

爲什麼不是摘要 – Trikaldarshi 2012-04-13 12:54:19

+3

「不允許被實例化」是'static class'的確切定義。你爲什麼需要別的東西? – 2012-04-13 12:55:44

回答

6

標記構造函數private。當然,這並不妨礙類通過static方法實例化自己,例如...

更實際的是,不允許類實例化的目的是什麼。如果它有一個單身人士,那麼private構造函數是適當的。如果要強制子類化,則使類abstract更好;如果是有實用方法的課程,則使其成爲static是一種方法(那麼您只能擁有static方法)。

+1

我做到了,但它不工作仍然可以創建obj。 – 2012-04-13 12:52:24

+2

@RomeshSomani它取決於你試圖從哪裏創建實例。它需要完全否認它,使其變得抽象。編輯 - 對不起,我的意思是靜態的。 – asawyer 2012-04-13 12:53:12

+0

不,抽象的目的不同。使其靜態。 – 2012-04-13 12:54:37

14

馬克構造(或多個)privateprotected或者從其他組件中使用,internal

+5

它仍然可以使用反射實例化。如果它不是密封的,你可以從它派生出來,然後使用你現在可以訪問的受保護的構造函數。 – jason 2012-04-13 12:55:24

+0

@Jason這些都是好點! – asawyer 2012-04-13 12:56:23

3

I need to know how to prevent a class from being Instantiated in .net?

你的問題不明確。

你的意思是在運行時實例化嗎?製作課程abstractstatic

你的意思是說構造函數在代碼中是不可訪問的嗎?使構造函數private。但請注意,有人仍然可以使用反射來獲取構造函數的句柄並在運行時實例化一個實例。

那麼,你的意思是?

+0

我忘了反思,好點。 – asawyer 2012-04-13 12:54:47

+0

我試圖用私人構造函數使用Activator.CreateInstance並引發異常 – 2012-04-13 12:55:17

+0

@AdrianIftode檢查您的綁定是否拉動私人成員。 – asawyer 2012-04-13 12:55:55

19

使類靜態是最好的辦法,如果你絕對不想要任何實例。這會阻止任何人從創建實例。該課程將被密封摘要,並且不會有任何構造函數。

此外,該語言會注意到它是一個靜態類,並阻止您在各個地方使用它,其中意味着實例,例如,類型參數和變量。這比僅僅使用私有構造函數更清楚地表明意圖 - 這可能意味着在該類中創建了實例(例如,用於單例實現)。

哦,使得類的靜態將阻止你在課堂上引入任何無謂的實例成員,太:)

有關靜態類的詳細信息,請參閱MSDN

+0

關於靜態類的好奇,他們不[看起來像類](http://codecrafter.blogspot.ca/2009/09/c-static-classes-are-not-real-classes.html);他們更類似於模塊... – 2012-04-13 13:03:47

2

如果問題是:

How can you make your class not be instanced without having your class be static or abstract ?

那麼這個問題的答案是落實singleton pattern,這英寸

public sealed class myClass 
{ 
    private static readonly Lazy<myClass> lazyInstance = 
     new Lazy<myClass>(() => new myClass()); 

    public static Instance 
    { 
     get 
     { 
      return lazyInstance.Value; 
     } 
    } 

    private myClass() 
    { 
     // constructor logic here 
    } 
} 

單例模式允許你通過周圍類爲方法的參考,同時還要確保你只有你的類的一個實例:NET 4+這與輕鬆完成。它還使得測試更容易,因爲您可以使用myClass實現的ImyClass實例,這在製作模擬對象時非常有用。

沒有.NET4你仍然可以實現單件模式,例如:

private static readonly myClass instance = new myClass(); 

public static Instance 
{ 
    get 
    { 
     return instance; 
    } 
} 

// rest of code remains the same 

不具有延遲加載,直到它的名字,還有很多其他的方法,以及(我想大約6種不同的方式),但以上兩種是最常見的。

總之,問題可能是詢問你是否知道單例模式,以及是否認識到它對於單元測試和模擬對象的靜態類的重要性。

正如其他人已經指出的那樣,static字段,甚至那些標記爲readonly的字段都可以設置反射,另外private構造函數可以使用反射來調用。如果您需要防止這些問題發生,您可能需要將調用代碼放在信任度較低的應用程序域空間中,否則您需要將您的類實現爲static。儘管如此,人們並不打擾這樣的反思層次來繞過你的約束,除非他們'真的需要'例如編寫模糊/極端條紋的單元測試。