Свойства частного установщика в инициализации объекта C # 3.0 - PullRequest
11 голосов
/ 14 июля 2009

Если у меня есть следующий код:

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.myName' не может быть использован в этом контексте, потому что установленный аксессор недоступен

Итак, есть ли способ добиться установки этого значения с помощью инициализации объекта? Если есть, как правильно это сделать?

Ответы [ 4 ]

13 голосов
/ 14 июля 2009

Нет, нет способа достичь этого. Инициализаторы объектов позволяют вам получать доступ только к полям и свойствам, которые иначе были бы доступны вне инициализатора.

Лучший вариант - использовать конструктор, который явно устанавливает эти свойства.

6 голосов
/ 14 июля 2009

Приватный набор на 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 - это private.

5 голосов
/ 14 июля 2009

Если их нужно установить при инициализации, рассмотрите возможность передачи их в качестве аргументов конструктору

1 голос
/ 14 июля 2009

У меня было это требование и в прошлом для OR / M. В основном я использую реальное свойство с полем бэкера и проверяю, установлено ли это свойство. Если так, бросьте исключение.

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; } 
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...