C# 防止类被实例化的最佳方法?

C# 防止类被实例化的最佳方法?,c#,C#,我需要知道如何防止类在.net中实例化 我知道一些方法,比如使类抽象和静态 还有其他方法可以实现这一点吗?将构造函数标记为私有的。当然,这并不能阻止类通过静态方法来实例化自己,例如 实际上,禁止类实例化的目的是什么。如果它有一个单例,那么一个private构造函数是合适的。如果是强制子类化,那么让类抽象更好;如果要使类具有实用方法,则将其设置为静态是一种方法(那么您只能使用静态方法)。标记构造函数私有,受保护,或者如果从另一个程序集使用,内部 我需要知道如何防止类在.net中实例化 你的问题不清

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

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


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

将构造函数标记为私有的。当然,这并不能阻止类通过
静态方法来实例化自己,例如

实际上,禁止类实例化的目的是什么。如果它有一个单例,那么一个
private
构造函数是合适的。如果是强制子类化,那么让类
抽象
更好;如果要使类具有实用方法,则将其设置为
静态
是一种方法(那么您只能使用
静态
方法)。

标记构造函数
私有
受保护
,或者如果从另一个程序集使用,
内部

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

你的问题不清楚

你是说在运行时实例化?使类
抽象
静态

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


那么,您的意思是什么呢?

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

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

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

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

如果问题是:

如果没有类,如何使类不被实例化 是静态的还是抽象的

然后,解决这个问题的方法是实现,在.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
    }
}
它在调用之前没有延迟加载,还有很多其他方法(我认为有6种不同的方法),但上面两种是最常见的

总之,这个问题可能是问您是否知道单例模式,以及您是否认识到它对于单元测试和模拟对象来说比静态类更重要

正如其他人已经指出的,
static
字段,甚至那些标记为
readonly
的字段也可以使用反射进行设置,此外,还可以使用反射调用
private
构造函数。如果需要防止这些问题,则需要使调用代码在不太可信的应用程序域空间中运行,或者需要将类实现为
static


不过,一般来说,人们不会为了绕过您的约束而费心考虑这些级别的反射,除非他们“真的需要”,例如,编写模糊/极端的边缘案例单元测试。

@RomeshSomani这取决于您试图从何处创建实例。你需要完全否认它,把它抽象化。编辑-对不起,我指的是静态的。不,抽象有不同的用途。我试图用一个私有构造函数使用Activator.CreateInstance,但它引发了一个exception@AdrianIftode检查绑定是否正在提取私有成员。@asawyer,我忘记了(我使用了Activator.CreateInstance)错误:抽象类不能被密封或静态。您的意思是“
密封的
抽象的
静态的
”?它仍然可以使用反射进行实例化。如果它不是一个密封的类,您可以从它派生,然后使用您现在可以访问的受保护构造函数。“不允许实例化”是
静态类的确切定义。为什么还需要其他东西呢?静态类的奇怪之处在于,它们不需要;它们更类似于模块。。。
private static readonly myClass instance = new myClass();

public static Instance
{
    get
    {
        return instance;
    }
}

// rest of code remains the same