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

Может ли класс в С# 6.0 иметь защищенный первичный конструктор?

Этот класс:

class Person 
{
    public Person(string firstName, string lastName)
    {
        _firstName = FirstName;
        _lastName = lastName;
    }

    private readonly string _firstName; // Make it really immutable
    public string FirstName
    {
        get
        {
            return _firstName;
        }
    }

    private readonly string _lastName; // Make it really immutable
    public string LastName
    {
        get
        {
            return _lastName;
        }
    }
}

Можно переписать в С# версия 6.0 с конструктором primary как:

class Person(string firstName, string lastName)
{
    public string FirstName { get; } = firstName;
    public string LastName { get; } = lastName;
}

Можно ли предоставить основному конструктору другой модификатор, как в следующем классе?

abstract class Person 
{
    protected Person(string firstName, string lastName)
    {
        _firstName = FirstName;
        _lastName = lastName;
    }

    private readonly string _firstName; // Make it really immutable
    public string FirstName
    {
        get
        {
            return _firstName;
        }
    }

    private readonly string _lastName; // Make it really immutable
    public string LastName
    {
        get
        {
            return _lastName;
        }
    }
}
4b9b3361

Ответ 1

РЕДАКТИРОВАТЬ: В этом ответе рассказывается о предварительной версии С# 6.0. Окончательная версия С# 6.0 не содержит первичных конструкторов.


Заметки о дизайне языка за 21 апреля говорят (и я не нашел более позднюю ссылку на это):

Отдельная доступность по типу и первичному конструктору

Существуют сценарии, в которых вы не хотите, чтобы конструкторы вашего типа имели такую ​​же доступность, как и тип. Обычным является случай, когда тип является общедоступным, но конструктор является частным или защищенным, а объект строится только через фабрики.

Следует ли нам придумать синтаксис, чтобы первичный конструктор мог получить различную доступность, чем его тип?

Заключение

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

Итак, нет, невозможно объявить первичный конструктор как protected. Хотя, как уже указывалось, нет никакой разницы между конструкторами public и protected для класса abstract.

Ответ 2

Нет, синтаксис определения основного конструктора по умолчанию задает многие характеристики конструктора:

  • Он всегда открыт.
  • У него никогда не было ничего в теле, кроме инициализации члена (кажется, что это зависит от разных версий предварительного просмотра, и никто еще не знает, что будет в последней спецификации С# 6.0)
  • Тот же базовый конструктор будет вызываться из всех конструкторов производного класса (потому что остальные передаются первичному конструктору)

и др.

(В этом обсуждается функция, которая еще не выпущена, она может измениться в других версиях)

Ответ 3

Основной конструктор разделяет модификатор доступа с классом, поэтому вы можете сделать его public или internal, , пока класс, который вы объявляете, имеет тот же уровень доступа. Вы не можете иметь класс public с основным конструктором internal или protected.

Однако, в вашем случае, даже если конструктор public, никто не сможет вызвать его напрямую, потому что ваш класс abstract, и вы не можете создать экземпляр абстрактного класса. Вы должны создать экземпляр класса, который наследует его, и не является abstract.

PS Я знаю, что это не часть вопроса, но я вижу, что вы уже приняли ответ, который содержит дополнительную информацию о первичных конструкторах, что неверно. Основной конструктор может иметь тело!

(...) можно указать тело основного конструктора просто заключая его в фигурные скобки внутри объявленного типа:

public class Customer(string first, string last)
{
    {
        if (first == null) throw new ArgumentNullException("first");
        if (last == null) throw new ArgumentNullException("last");
    }

    public string First { get; } = first;
    public string Last { get; } = last;
}

Вы можете больше узнать о новых функциях С# на странице Roslyn на codeplex, например. в этом документе: https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status