Подтвердить что ты не робот

В чем разница между классом, имеющим частный конструктор, и закрытым классом, имеющим частный конструктор?

Есть ли разница между A и B?

Класс A имеет частный конструктор:

class A
{
    private A()
    { }
}

Класс B запечатан и имеет частный конструктор:

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

Ответ 1

Да A может наследоваться вложенным классом, а B не может быть унаследован вообще. Это совершенно законно:

public class A {
  private A() { }

  public class Derived : A { }
}

Обратите внимание, что любой код может создать new A.Derived() или наследовать от A.Derived (его конструктор является общедоступным), но никакие другие классы вне исходного текста A не могут наследовать непосредственно из A.

Типичное использование для чего-то подобного - это класс с enum-подобными значениями, но который может иметь пользовательское поведение:

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();
}

Ответ 2

Основываясь на второй статье, если это единственный конструктор, вы не сможете создать экземпляр класса A или класса B. Поскольку класс A имеет частный конструктор, вы не можете извлечь из него из-за его уровня защиты и не можете вы выходите из B с запечатанным.

Наследование (Руководство по программированию на С#)

Доступ к производному классу для базовых классов класса У производного класса есть доступ общественным, защищенным, внутренним и защищенным внутренним членам базовый класс. Даже если производный класс наследует частных членов базового класса, он не может получить доступ к этим членам. Однако все эти частные члены все еще присутствуют в производном классе и могут выполнять та же самая работа, которую они будут делать в базовом классе. Например, предположим, что что защищенный метод базового класса обращается к частному полю. Что поле должно присутствовать в производном классе для унаследованной базы класс для правильной работы.

Частные конструкторы (Руководство по программированию на С#)

Частный конструктор является специальным конструктором экземпляра. это обычно используется в классах, содержащих только статические члены. Если класс имеет один или несколько частных конструкторов и не имеет общих конструкторов, то другим классам (кроме вложенных классов) не разрешено создавать экземпляры этого класса.

Ответ 3

Есть одна крошечная разница, которую вы можете получить, с анализом кода.

Рассмотрим этот код:

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, потому что мы получаем доступ к виртуальному методу, который является A Bad Thing.

Однако, если вы закроете Derived, предупреждение о анализе кода исчезнет.

Итак, для вас крошечная и надуманная разница.;)

Ответ 4

Класс sealed может быть создан, но класс с частным конструктором не может. Они оба не допускают наследование, но это не цель частного конструктора.

Причина, по которой вы используете частный конструктор, заключается в прекращении создания экземпляра. Это часто используется в статических factory методах, где вы должны вызвать MyClass::Create(...) для создания экземпляра.

Это не имеет ничего общего с герметизацией, которая останавливает наследование. Если вы используете закрытый конструктор для прекращения наследования, вы используете неправильный подход. Есть способы обойти частный конструктор для наследования.

Ответ 5

Если класс запечатан, невозможно определить класс, который вытекает из него. Класс с частным конструктором может быть создан методами factory внутри класса и не унаследован вложенными классами (которые в зависимости от их уровня доступа и конструкторов могут быть наследованы внешним кодом). Кроме того, произвольный внешний код может объявлять классы, которые вытекают из него и удовлетворяют ограничению new(). Если производный класс не может вызвать базовый конструктор, его собственные конструкторы не будут иметь альтернативы, кроме как выбросить исключение, сбой или зависание, но такое поведение не будет обнаружено до тех пор, пока не будет предпринята попытка фактически создать экземпляр; код будет компилироваться отлично.

Ответ 6

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() Выполнить().); Debug.WriteLine(Test.GetDerivedTestRequest() Выполнить().);

=============================================== ============= Выход:

частный конструктор был вызван в классе Test Test.Run

частный конструктор был вызван в классе Test публичный конструктор был вызван в производном классе DerivedTest. DerivedTest.Run

Итак, вложенный класс может быть выведен из внешнего базового класса, имеющего единственный частный конструктор.