【问题标题】: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() { }
    }

问题:

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

【问题讨论】:

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

标签: c# class constructor static access-modifiers


【解决方案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. 类的任何静态成员都被引用。
      猜你喜欢
      • 2011-05-30
      • 2020-06-16
      • 2021-06-10
      • 1970-01-01
      • 2014-08-29
      • 2012-11-23
      • 2013-08-29
      • 1970-01-01
      • 2016-04-07
      相关资源
      最近更新 更多