30

A和B有区别吗?

A 类有私有构造函数:

class A
{
    private A()
    { }
}

B 类是密封的并且有一个私有构造函数:

sealed class B
{
    private B()
    { }
}
4

6 回答 6

42

YesA可以被嵌套类继承,而B根本不能被继承。这是完全合法的:

public class A {
  private A() { }

  public class Derived : A { }
}

请注意,任何代码都可以创建new A.Derived()或继承自A.Derived(其构造函数是公共的),但源文本之外的任何其他类都A不能直接继承自A.

此类的典型用途是具有类枚举值但可以具有自定义行为的类:

public abstract class A {
  private A() { }

  public abstract void DoSomething();

  private class OneImpl : A { 
    public override void DoSomething() { Console.WriteLine("One"); }
  }

  private class TwoImpl : A { 
    public override void DoSomething() { Console.WriteLine("Two"); }
  }

  public static readonly A One = new OneImpl();
  public static readonly A Two = new TwoImpl();
}
于 2013-05-19T21:33:11.713 回答
5

根据第二篇文章,如果这是唯一的构造函数,您将无法创建 A 类或 B 类的实例。因为 A 类有一个私有构造函数,由于其保护级别,您不能从它派生,也不能从它派生B带密封。

继承(C# 编程指南)

派生类对基类成员的访问 派生类可以访问基类的公共、受保护、内部和受保护的内部成员。即使派生类继承了基类的私有成员,它也不能访问这些成员。但是,所有这些私有成员仍然存在于派生类中,并且可以完成与基类本身相同的工作。例如,假设受保护的基类方法访问私有字段。该字段必须存在于派生类中,才能使继承的基类方法正常工作。

私有构造函数(C# 编程指南)

私有构造函数是一种特殊的实例构造函数。它通常用于仅包含静态成员的类中。如果一个类有一个或多个私有构造函数而没有公共构造函数,则其他类(嵌套类除外)不允许创建该类的实例。

于 2013-05-19T21:22:33.803 回答
5

您可以得到一个微小的差异,与代码分析有关。

考虑这段代码:

public class Base
{
    public virtual void Function()
    {
    }
}

public class Derived: Base
{
    public static  Derived Create()
    {
        return new Derived();
    }

    private Derived()
    {
        // Code analysis warning: CS2214 "Do not call overridable methods in constructors".
        Function(); 
    }
}

Derived 构造函数有一个代码分析警告,因为我们正在从它访问一个虚拟方法,这是一个坏事。

但是,如果您进行Derived密封,代码分析警告就会消失。

所以对你来说有一个微小的和人为的差异。;)

于 2013-05-19T21:30:56.203 回答
2

可以实例化一个sealed类,但不能实例化具有私有构造函数的类。它们都不允许继承,但这不是私有构造函数的目标。

使用私有构造函数的原因是停止实例化。这通常用在静态工厂方法中,您必须调用MyClass::Create(...)它来创建实例。

这与阻止继承的密封无关。如果您使用私有构造函数来停止继承,那么您使用的是错误的方法。有一些方法可以绕过私有构造函数进行继承。

于 2013-05-19T21:26:21.057 回答
0
public class Test
{


    private Test()
    {
        Debug.WriteLine("private constructor has been called in class Test");
    }

    public virtual string Run()
    {
        return "Test.Run";
    }

    public static Test GetTestRequest()
    {
        return new Test(); 
    }

    public static DerivedTest GetDerivedTestRequest()
    {
        return new DerivedTest();
    }

    public class DerivedTest:Test
    {
        public DerivedTest()
        {
            Debug.WriteLine("public constructor has been called in derived class DerivedTest.");
        }

        public override string Run()
        {
            return "DerivedTest.Run";
        }
    }
}

Debug.WriteLine(Test.GetTestRequest().Run()); Debug.WriteLine(Test.GetDerivedTestRequest().Run());

==================================================== ========== 输出:

在类 Test Test.Run 中调用了私有构造函数

在类测试中调用了私有构造函数 在派生类 DerivedTest 中调用了公共构造函数。派生测试运行

因此,嵌套类可以从具有唯一私有构造函数的外部基类派生。

于 2014-10-14T17:06:49.787 回答
0

如果一个类是密封的,就不能定义一个派生自它的类。具有私有构造函数的类可以由类内的工厂方法实例化,也不能由嵌套类继承(取决于它们的访问级别和构造函数,可以由外部代码继承)。此外,任意外部代码可以声明派生自它并满足new()约束的类。如果派生类不能调用基类构造函数,它自己的构造函数将别无选择,只能抛出异常、崩溃或挂起,但在尝试实际构造实例之前,无法检测到此类行为;代码编译得很好。

于 2013-05-24T15:45:26.777 回答