2012-04-13 64 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。尽管如此,人们并不打扰这样的反思层次来绕过你的约束,除非他们'真的需要'例如编写模糊/极端条纹的单元测试。