嵌套类中的空私有构造函数是否有任何意义

本文关键字:构造函数 是否 任何意 嵌套 | 更新日期: 2023-09-27 18:37:25

我遇到了一个带有如下嵌套类的源代码:

public class OuterClass
{
  // code of the outer class
  protected class NestedClass
  {
    private string myVar;
    private NestedClass() {} // <--- empty private ctor
    public NestedClass(string myVar)
    {
      this.myVar = myVar;
    } 
  }
}

创建这个空的私有构造函数的原因可能是什么?

我知道在实现单例时,构造函数必须是私有的,以防止其他类创建实例。但是,在这种情况下,这是另一个公共构造函数,因此这不能成为原因。

我想到的一个原因是不允许创建一个没有变量值的实例,该值作为参数传递给公共构造函数,但据我所知,当简单没有其他构造函数时,这应该是不可能的公共构造函数带参数。这是对的吗?

编辑:现在删除的答案提到了默认构造函数。据我所知,"隐藏"默认构造函数仅在根本没有手动编写的构造函数时才存在。此处对此进行了描述:

这些构造函数注入到不引入其他构造函数的所有类声明中。

因此,我的嵌套类的空构造函数不是默认构造函数,而只是没有参数的构造函数。我假设顶级类和嵌套类都是这种情况。

嵌套类中的空私有构造函数是否有任何意义

如果您有非默认构造函数并且未指定默认构造函数,则任何代码都无法访问默认构造函数,因为编译器不会创建一个。

如果您有非默认构造函数

并且还指定了私有默认构造函数,则 NestedClass 方法可以使用默认构造函数。您的代码不执行此操作,因此无需提供默认构造函数(私有或其他)。

还有一个晦涩难懂的情况,它可以有所作为:通过提供默认的NestedClass构造函数,您可以启用反射来访问它。

以下程序演示。

如果你运行它,它将打印"Demo.OuterClass+NestedClass"。

如果您注释掉私有默认NestedClass构造函数并运行它,它将崩溃。

除了这种不太可能的情况,我看不出提供私有构造函数的合理理由。

using System;
using System.Reflection;
namespace Demo
{
    public class OuterClass
    {
        protected class NestedClass
        {
            private string myVar;
            private NestedClass(){} // Commenting-out this line will cause the reflection to break.
            public NestedClass(string myVar)
            {
                this.myVar = myVar;
            }
        }
    }
    public class MyDerivedClass: OuterClass
    {
        public MyDerivedClass()
        {
            Type type = typeof(NestedClass);
            var ctor = type.GetConstructor(BindingFlags.Instance|BindingFlags.NonPublic, null, Type.EmptyTypes, null);
            var nested = (NestedClass) ctor.Invoke(null);
            Console.WriteLine(nested);
        }
    }
    public static class Program
    {
        private static void Main()
        {
            var test = new MyDerivedClass();
        }
    }
}

如果你不想显式允许反射调用私有默认构造函数,那么我会说提供它确实没有意义,你应该从代码中删除它。

我认为

这意味着只有这个类可以使用这个构造函数创建自己的实例。类中的代码是否在任何地方调用此构造函数?

通常,如果该类想要限制您调用在其上定义的某种工厂方法以创建它,您将拥有一个私有构造函数,但由于定义了另一个构造函数,因此情况似乎并非如此。

您可以使用反射来定位私有构造函数,一旦您获得了私有构造函数的 ConstructorInfo,您就可以调用它以创建类的实例,但这将是一件非常小众的事情!