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

これが唯一のコンストラクターである場合、2 番目の記事に基づいて、クラス A またはクラス B のインスタンスを作成することはできません。 B シール付き。

継承 (C# プログラミング ガイド)

基本クラスのメンバーへの派生クラスのアクセス 派生クラスは、基本クラスの public、protected、internal、および protected internal メンバーにアクセスできます。派生クラスは基本クラスのプライベート メンバーを継承しますが、それらのメンバーにアクセスすることはできません。ただし、これらのプライベート メンバーはすべて派生クラスに存在し、基本クラス自体で行うのと同じ作業を行うことができます。たとえば、保護された基本クラスのメソッドがプライベート フィールドにアクセスするとします。継承された基本クラスのメソッドが正しく機能するには、そのフィールドが派生クラスに存在する必要があります。

プライベート コンストラクター (C# プログラミング ガイド)

プライベート コンストラクターは、特別なインスタンス コンストラクターです。通常、静的メンバーのみを含むクラスで使用されます。クラスに 1 つ以上のプライベート コンストラクターがあり、パブリック コンストラクターがない場合、他のクラス (入れ子になったクラスを除く) はこのクラスのインスタンスを作成できません。

于 2013-05-19T21:22:33.803 に答える
5

コード分​​析に関係する小さな違いが 1 つあります。

次のコードを検討してください。

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

クラスが封印されている場合、そこから派生するクラスを定義することはできません。プライベート コンストラクターを持つクラスは、クラス内のファクトリ メソッドによってインスタンス化されることも、ネストされたクラスによって継承されることもありません (アクセス レベルとコンストラクターによっては、外部コードによって継承される場合があります)。さらに、任意の外部コードは、そこから派生し、制約を満たすクラスを宣言できます。new()派生クラスが基本コンストラクターを呼び出すことができない場合、独自のコンストラクターは、例外をスローするか、クラッシュまたはハングする以外に方法はありませんが、そのような動作は、実際にインスタンスを構築しようとするまで検出できません。コードは正常にコンパイルされます。

于 2013-05-24T15:45:26.777 に答える