静态类与受保护的构造函数

Posted

技术标签:

【中文标题】静态类与受保护的构造函数【英文标题】:Static Class vs Protected Constructor 【发布时间】:2018-06-15 07:43:18 【问题描述】:

我在课堂上收到警告消息,例如

在类声明中添加Protected 构造函数或static 关键字

解决方案

我尝试了以下两种方法后错误消失了,

static 没有constructor 的类

public static class Program    
    

static 类与 protected 使用构造函数

public  class Program
    
        protected Program()  
    

问题:

那么我上面的解决方案中提到的有什么区别?哪个最好用?

【问题讨论】:

您可能只有静态成员,并且分析器假定您不希望能够创建类的实例。 你能解释一下你们为什么要投反对票吗? 我认为您需要重新表述您的问题。这不是关于有什么区别,而是关于为什么要求您这样做 我个人会稍微格式化一下 ;-) 不要以为评论的人就是投反对票的人。 【参考方案1】:

static 类不需要实例来访问其成员。 static 类不能有实例成员(例如,public int MyNumber; 不允许在静态类上使用,因为在静态类上只允许使用静态成员)。但是,非静态类中允许实例和静态成员。具有protected 构造函数的类只能有一个自己创建的实例或从它继承的东西。

public class Program

    protected Program()
    
        // Do something.
    

    public static Program Create()
    
        // 100% Allowed.
        return new Program();
    

    public void DoSomething()
    

    


public static class AnotherClass

    public static Program CreateProgram()
    
        // Not allowed since Program's constructor is protected.
        return new Program();
    


public class SubProgram : Program

    protected SubProgram()
    
        // Calls Program() then SubProgram().
    

    public new static Program Create()
    
        // return new Program(); // We would need to move the SubProgram class INSIDE the Program class in order for this line to work.
        return new SubProgram();
    


Program.Create();               // Can be called since Create is public and static function.
Program.DoSomething()           // Can't be called because an instance has not been instantiated.
var test = Program.Create();
test.DoSomething();             // Can be called since there is now an instance of Program (i.e. 'test').
AnotherClass.CreateProgram();   // Can't be called since Program's constructor is protected.
SubProgram.Create();            // Can be called since SubProgram inherits from Program.

至于性能,这种区别实际上与性能没有太大关系。

【讨论】:

【参考方案2】:

您可能在类中只有静态成员,并且代码分析器假定您的意图是无法创建该类的实例,因此它要求您将类设为静态

public static class Program 
    //...static members

或放置一个受保护/私有的构造函数

public class Program 
    protected Program  //OR private

    

    //...static members

防止该类的实例被初始化。

静态类与非静态类基本相同,但有一个区别:静态类不能实例化。

参考Static Classes and Static Class Members (C# Programming Guide)

受保护的构造函数意味着只有派生类可以调用构造函数

私有构造函数不允许任何其他类使用私有构造函数初始化该类

【讨论】:

【参考方案3】:

静态构造函数:类类型实例化时调用一次,用于初始化静态成员。不创建类的实例。

受保护的构造函数:只能由类或继承它的类调用的构造函数。

对此的最佳实践是,如果您只希望继承的类能够创建您的类的实例,您应该有一个用于初始化静态成员的静态构造函数和一个受保护的构造函数。两者都可以。

public class MyClass

    static readonly long _someStaticMember;
    private bool _param;
    static MyClass()
    
        //Do Some Logic
        _someStaticMember = SomeValueCalculated;
    
    protected MyClass(bool param)
    
        _param = param;
    

public class ChildClass: MyClass

    public ChildClass(bool param) : base(param);

public class NotChildClass

    public MyClass someObject = new MyClass(true); //Will Fail

【讨论】:

请注意:类的static constr 在给定的应用程序域中最多执行一次。 static constr 的执行由在应用程序域中发生的以下事件中的第一个触发:1. 创建类的实例。 2. 类的任何静态成员都被引用。【参考方案4】:

实例化类类型时调用静态构造函数。在创建类的实例时调用受保护的构造函数。受保护的部分意味着只有继承该类的类才能调用它。

【讨论】:

类类型实例化时调用静态构造函数静态类可以有构造函数吗?? @RameshRajendran 是的,这意味着正在构建类,而不是它的实例。 如何处理的?已构造但无法创建实例? 请注意:类的static constr 在给定的应用程序域中最多执行一次。 static constr 的执行由在应用程序域中发生的以下事件中的第一个触发:1. 创建类的实例。 2. 类的任何静态成员都被引用。

以上是关于静态类与受保护的构造函数的主要内容,如果未能解决你的问题,请参考以下文章

是否可以在 C++ 中将返回值移动语义与受保护的复制构造函数一起使用?

抽象类与私有构造函数

派生类中的静态方法可以在 C++ 中调用受保护的构造函数吗?

类与对象:课后作业1

java中成员变量代码块构造函数运行顺序

静态函数范围对象的构造是线程安全的吗?