Свойства Private-setter в инициализации объекта C# 3.0
Если у меня есть следующий код:
public class MyClass
{
public string myName { get; private set; }
public string myId { get; set; }
}
для сеттера создается частная сгенерированная компилятором переменная. Я хочу, чтобы сеттер не был доступен только для инициализации объекта. Но как я могу изначально установить переменную myName?
читать об инициализации объекта я нашел следующее:
... это только для чтения и частное поле, представляющее базовый хранения имя, сгенерированное компилятором не может использовать в конструкторе для назначения к нему. Решение заключается в использовании [...] объект инициализаторы
решение было бы, тогда, использовать:
MyClass mc = new MyClass {
myName = "What ever",
myId = "1234"
};
но это заканчивается ошибкой компилятора, говорящей, что:
свойство или индексатор 'Класса MyClass.Класса MyClass.моеимя' не может использоваться в этом контексте, поскольку метод доступа set недоступен
Итак, есть ли способ достичь установки этого значения с помощью инициализации объекта? Если есть, как это правильно сделать?
4 ответов
частный набор на myName означает, что вы можете только инициализировать (установить) его от чего-то, что является членом MyClass. Например:
public class MyClass {
public string myName { get; private set; }
public string myId { get; set; }
public static MyClass GetSampleObject() {
MyClass mc = new MyClass
{
myName = "Whatever",
myId = "1234"
};
return mc;
}
}
(Я скопировал и вставил ваш код инициализации в GetSampleObject метод).
но если вы попытаетесь установить его за пределами MyClass, вы получаете ошибку компилятора, потому что private является частным.
нет нет никакого способа достичь этого. Инициализаторы объектов позволяют получить доступ только к полям и свойствам, которые в противном случае были бы доступны за пределами инициализатора.
лучшим вариантом является использование конструктора, который явно задает эти свойства.
Если они должны быть установлены при инициализации, то рассмотрите возможность передачи их как args конструктору
у меня было это требование в прошлом, а также для or / M вещей. В основном я использую недвижимость с полем backer и проверяю, установлено ли это свойство. Если это так, исключение.
public string myName
{
get{ return _myName; }
set
{
if( _myName != null && _myName != value )
throw new Exception( "The myName property may only be set once." );
_myName = value;
}
}
private string _myName;
и другой вариант для совместимости OR/M, который также использует инициализацию конструктора:
public class MyClass
{
[Obsolete( "For ORM use only!" )]
[EditorBrowsableState( EditorBrowsableState.Never )]
public MyClass(){}
public MyClass( string name ){ myName = name; }
public string myName { get; private set; }
public string myId { get; set; }
}