【问题标题】:Best way to prevent a class from being Instantiated?防止类被实例化的最佳方法?
【发布时间】:2012-04-13 12:50:02
【问题描述】:

我需要知道如何防止类在 .net 中被实例化?

我知道一些方法,比如制作抽象类和静态类。

还有其他方法可以实现吗?

【问题讨论】:

  • “不允许被实例化”是static class的确切定义。为什么你需要别的东西?

标签: c#


【解决方案1】:

如果您绝对不想要任何实例,则将类设为静态是最好的方法。这会阻止 任何人 创建实例。该类将是密封的抽象,并且不会有任何构造函数。

此外,该语言会注意到它是一个静态类,并阻止您在暗示实例的各个地方使用它,例如类型参数和变量。这比仅仅拥有一个私有构造函数更清楚地表明了意图 - 这可能意味着在该类中创建了一些实例(例如,对于单例实现)。

哦,将类设为静态也会阻止您在类中引入任何无意义的实例成员 :)

有关静态类的更多信息,请参阅MSDN

【讨论】:

【解决方案2】:

标记构造函数privateprotected,或者如果在其他程序集中使用,则标记internal

【讨论】:

  • 它仍然可以使用反射来实例化。如果它不是密封的,你可以从它派生,然后使用你现在可以访问的受保护的构造函数。
【解决方案3】:

标记构造函数private。当然,这并不妨碍类通过static方法实例化自己,例如...

更实际地,禁止类实例化的目的是什么。如果它有一个singleton,那么一个private 构造函数是合适的。如果是强制子类化,则制作类abstract更好;如果要拥有一个带有实用方法的类,则将其设为static 是一种方法(那么您只能拥有static 方法)。

【讨论】:

  • @RomeshSomani 这取决于您尝试从哪里创建实例。你需要完全否认它,让它抽象。编辑 - 对不起,我的意思是静态的。
  • 不,摘要有不同的目的。使其成为静态的。
【解决方案4】:

我需要知道如何防止类在 .net 中被实例化?

你的问题不清楚。

你的意思是在运行时实例化?将课程设为abstractstatic

你的意思是构造函数在代码中不可访问吗?使构造函数private。但请注意,仍然有人可以使用反射来获取构造函数的句柄并在运行时实例化实例。

那么,你是什么意思?

【讨论】:

  • 我尝试将 Activator.CreateInstance 与私有构造函数一起使用,但它引发了异常
  • @AdrianIftode 检查您的绑定是否正在拉取私有成员。
  • @asawyer,我忘记了(我使用了 Activator.CreateInstance)
  • 错误:抽象类不能被密封或静态。您的意思是“sealedabstractstatic”?
【解决方案5】:

如果问题是:

如果没有你的类,如何让你的类不被实例化 是static 还是abstract

那么这个问题的答案是实现singleton pattern,在.NET 4+中这很容易做到:

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

单例模式允许您将类作为对方法的引用传递,同时仍然确保您只有一个类的实例。它还使测试变得更加容易,因为您可以拥有 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

一般来说,除非他们“确实需要”例如编写晦涩/极端的边缘案例单元测试,否则人们不会费心进行这种级别的反思来绕过您的限制。

【讨论】:

    猜你喜欢
    • 2021-05-11
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 2015-06-09
    • 2017-10-30
    • 2010-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多