简体   繁体   English

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

[英]Best way to prevent a class from being Instantiated?

I need to know how to prevent a class from being Instantiated in .net? 我需要知道如何防止类在.net中实例化?

I know few methods like making the class Abstract and Static. 我知道几个方法,比如制作抽象和静态类。

Is there any more way to achieve this? 有没有更多的方法来实现这一目标?

Making the class static is the best approach, if you absolutely don't want any instances. 如果你绝对不想要任何实例,那么使类静态是最好的方法。 This stops anyone from creating instances. 这会阻止任何人创建实例。 The class will be both sealed and abstract, and won't have any constructors. 该类将是密封抽象的,并且不会有任何构造函数。

Additionally, the language will notice that it's a static class and stop you from using it in various places which imply instances, eg type arguments and variables. 此外,该语言将注意到它是一个静态类,并阻止您在暗示实例的各个地方使用它,例如类型参数和变量。 This indicates the intention more clearly than just having a private constructor - which could mean that there are instances, created within that class (eg for a singleton implementation). 这表明意图比仅具有私有构造函数更清楚 - 这可能意味着在该类中创建了实例(例如,对于单例实现)。

Oh, and making the class static will stop you from introducing any pointless instance members in the class, too :) 哦,让类静态将阻止你在类中引入任何毫无意义的实例成员:)

See MSDN for more information about static classes. 有关静态类的更多信息,请参阅MSDN

将构造函数标记为privateprotected或者如果从另一个程序集中使用,则标记为internal

Marking the constructor private . 将构造函数标记为private Of course, this doesn't prevent the class from instantiating itself through a static method, for example... 当然,这并不妨碍类通过static方法实例化,例如......

More practically, what's the purpose of disallowing class instantiation. 更实际的是,禁止类实例化的目的是什么。 If it's to have a singleton , then a private constructor is appropriate. 如果它有一个单例 ,那么private构造函数是合适的。 If it's to force subclassing, making the class abstract is better; 如果要强制进行子类化,那么使类abstract更好; if it's to have a class with utility methods, making it static is one way (then you can only have static methods). 如果它有一个带有实用方法的类,那么将它设置为static是一种方式(那么你只能有static方法)。

I need to know how to prevent a class from being Instantiated in .net? 我需要知道如何防止类在.net中实例化?

Your question is not clear. 你的问题不明确。

Do you mean instantiated at runtime? 你的意思是在运行时实例化? Make the class abstract or static . 使类abstractstatic

Do you mean that the constructor is not accessible in code? 你的意思是代码中无法访问构造函数吗? Make the constructor private . 使构造函数private But note that someone could still use reflection to grab a handle on a constructor and instantiate an instance at runtime. 但请注意,有人仍然可以使用反射来获取构造函数上的句柄并在运行时实例化实例。

So, which do you mean? 那么,你的意思是?

If the question is: 如果问题是:

How can you make your class not be instanced without having your class be static or abstract ? 如果你的课程不是staticabstract ,你怎么能让你的课程不被实例化?

Then the answer to this is to implement the singleton pattern , which in .NET 4+ this is done easily with: 然后答案就是实现单例模式 ,在.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
    }
}

The singleton pattern allows you to pass your class around as a reference to methods, while still ensuring that you have only a single instance of your class. 单例模式允许您将类作为方法的引用传递给您,同时仍然确保您只有一个类的实例。 It also makes testing much easier as you can have a ImyClass instance which myClass implements, this is very helpful when making mock objects. 它还使测试变得更容易,因为你可以拥有myClass实现的ImyClass实例,这在制作模拟对象时非常有用。

Without .NET4 you can still implement the singleton pattern, for example: 如果没有.NET4,您仍然可以实现单例模式,例如:

private static readonly myClass instance = new myClass();

public static Instance
{
    get
    {
        return instance;
    }
}

// rest of code remains the same

Which doesn't have deferred loading until it's called, there's lots of other ways as well (I think about 6 different ways), but the above two are the most common ones. 在调用之前没有延迟加载,还有很多其他方法(我认为有6种不同的方式),但上面两种是最常见的方式。

In summary the question is likely asking if you know the singleton pattern and if you recognise it's importance over static classes for unit tests and mock objects. 总而言之,问题可能在于询问您是否知道单例模式以及您是否认识到它对于单元测试和模拟对象的静态类的重要性。

As others have already pointed out, static fields, even those marked readonly can be set with reflection, in addition the private constructor can be called using reflection. 正如其他人已经指出的那样, static字段,甚至那些标记为readonly字段都可以使用反射进行设置,此外可以使用反射调用private构造函数。 If you need to prevent these, either you need to make the calling code run in a less trusted app-domain space, or you will need to implement your class as static . 如果您需要阻止这些,您需要在不太受信任的应用程序域空间中运行调用代码,或者您需要将您的类实现为static

Generally though, people don't bother with such levels of reflection to get around your constraints unless they 'really need to' for example, writing obscure / extreme fringe case unit tests. 一般来说,人们不会为了绕过你的约束而烦恼这种反射水平,除非他们“真的需要”,例如,编写模糊/极端条纹单元测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 防止类被实例化 - Prevent a Class from being instantiated 防止从对象传递未使用的属性的最佳方法 - Best way to prevent unused properties from being passed from object 如何防止在工厂外实例化类 - How to keep a class from being instantiated outside of a Factory 在控制台应用程序中,防止转义命令行参数中特殊序列的最佳方法是什么? - in a console app what's the best way to prevent special sequences in command line arguments from being escaped? asp.net Core/OnPostAsync:防止记录被创建两次的最佳方法是什么? - asp.net Core/OnPostAsync: what's the best way to prevent a record from being created twice? 如何防止ASP.NET MVC控制器实例化和执行 - How to prevent an asp.net mvc controller from being instantiated and executed 在视图之间导航时,如何防止我的 ViewModel 被实例化两次? - How can I prevent my ViewModel from being instantiated twice when navigating between views? 防止“使用”使用框架类中的特定构造函数的最佳方法 - Best way to prevent “using” from using a specific constructor from a framework class 有没有办法可以防止 struct 被实例化,或者我可以有一个将被复制的类? - Is there a way I can prevent struct from being insantiated or can I have a class that will be copied? 防止类属性被序列化 - Prevent class property from being serialized
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM