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

11

我的课程中出现了一个警告信息,类似于:

enter image description here

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

解决方案

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

static类没有构造函数

public static class Program    {
    }

具有protected构造函数的非static

public  class Program
    {
        protected Program() { }
    }

问题:

那么,我上面的解决方案中提到的静态类和受保护构造函数之间有什么区别?哪一个是最好使用的?


2
你可能只有静态成员,分析器会认为你不想创建类的实例。 - Nkosi
请问可以解释一下为什么你们会投反对票吗? - Ramesh Rajendran
我认为你需要重新表达你的问题。这不是关于有什么区别,而是关于为什么要求你这样做。 - Nkosi
个人而言,我会稍微进行格式化;-) - Cleptus
5
不要假设那些评论的人就是给出反对票的人。 - Nkosi
@Nkosi同意。我只是告诉那个给负评的人在发表之前请说明理由 :) - Ramesh Rajendran
4个回答

6

静态类不需要实例即可访问其成员。静态类不能有实例成员(例如,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.

就性能而言,这个区别与性能没有太大关系。


4
你的类可能只有静态成员,代码分析器会认为你不想创建该类的实例,因此要求你将该类设置为静态。
public static class Program {
    //...static members
}

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

public class Program {
    protected Program { //OR private

    }

    //...static members
}

为了防止该类的实例被初始化,可以使用静态类。

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

参考 静态类和静态类成员 (C# 编程指南)

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

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


1
静态构造函数: 当类类型被实例化时仅调用一次,用于初始化静态成员。不会创建类的实例。
受保护的构造函数: 只能由该类或继承它的类调用的构造函数。
最佳实践是,应该有一个静态构造函数来初始化静态成员,如果您只想让继承的类能够创建类的实例,则应该有一个受保护的构造函数。两者都可以有。
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.引用类的任何静态成员。 - L. Guthardt

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

1
静态构造函数在类类型实例化时被调用。静态类可以有构造函数吗? - Ramesh Rajendran
1
是的,它意味着正在构建类,而不是它的实例。 - Yuriy Faktorovich
它是如何处理的?已构建但无法创建实例? - Ramesh Rajendran
1
请注意:对于一个类而言,static constr 最多在给定的应用程序域中执行一次。触发 static constr 的执行是由以下事件中最先发生的事件之一引起的:1. 创建该类的实例。2. 引用该类的任何静态成员。 - L. Guthardt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接