Пример:
public class Name {
public string FirstName { get; private set; }
public string LastName { get; private set; }
private Name() { }
public Name(string firstName, string lastName) {
FirstName = firstName;
LastName = lastName;
}
}
При попытке создать экземпляр этого класса C# intellisense показывает как закрытый, так и общедоступный конструкторы для ключевого слова new, даже если один из конструкторов является закрытым!
Что еще более странно, когда я удаляю второй аргумент из общедоступного конструктора (удаляя lastName как аргумент общедоступного конструктора), intellisense теперь правильно показывает только общедоступный конструктор с ключевым словом new.
Это ошибка или мне что-то здесь не хватает? Я использую VS2008 SP1.
изменить: ясность кода





Вау, это странно. Я просто попробовал это сам на своей копии VS2008 (я также использую SP1) и получил точно такие же результаты. Когда было несколько параметров, частный конструктор появлялся в Intellisense, но не тогда, когда был только один. Думаю, это ошибка.
Спасибо за подтверждение моего наблюдения. Думал, я единственный!
Не знаю, почему intellisense показывает вам странные вещи. Но у вас должен быть абстрактный базовый класс для ваших доменных объектов с общедоступным конструктором, поэтому вам не нужно добавлять в свои объекты частные. Вы также должны поместить туда свои свойства для ваших первичных ключей и т. д.
public abstract class BaseDomainObject{
public BaseDomainObject() { }
private int _id;
public virtual int Id { get { return _id; } set { _id = value; } }
}
public SomeDomainObject : BaseDomainObject{
...
}
Имя - это объект неизменяемого значения (DDD) для моих классов домена. Так что на самом деле не нужен абстрактный базовый класс.
Вероятно, это ошибка, но не стоит прилагать усилия для ее исправления. А именно потому, что существует множество сценариев, в которых доступ к частному конструктору разрешен. Возьмите следующий фрагмент кода. Доступ к частным конструкторам разрешен
class Outer {
private Outer() {
}
public Outer Create() { return new Outer(); }
class Inner() {
void Function1() { new Outer(); }
class DoubleInner() {
void Function2() { new Outer(); }
}
}
}
Да, это справедливо для внутренних классов, но для других пользователей API довольно неприятно видеть недопустимый конструктор. Есть ли лучший способ создать неизменяемый объект?
Не определяйте частный конструктор вообще. Если вы определяете явный конструктор, неявный конструктор не будет сгенерирован, и, следовательно, доступность не будет проблемой. Это применимо только к ссылочным типам, типы значений всегда будут иметь конструктор по умолчанию.
Несмотря на то, что частный конструктор отображается в Intellisense, компилятор по-прежнему выдает ошибку «недоступен из-за уровня защиты», если вы попытаетесь скомпилировать код, который использует его там, где это не разрешено.
В качестве побочного примечания мне нужен частный конструктор по умолчанию, чтобы удовлетворить требованиям NHibernate.