2008-09-14 7 views
78

В прошлом мы объявили такие свойства, как это:Как я могу получить доступ к переменной подстановки для объекта с автозаполнением?

public class MyClass 
{ 
    private int _age; 

    public int Age 
    { 
      get{ return _age; } 
      set{ _age = value; } 
    } 
} 

Теперь мы можем сделать:

public class MyClass 
{ 
    public int Age {get; set;} 
} 

Мой вопрос, как я могу получить доступ к частной переменной, которая создается автоматически с помощью этих обозначений?

Я бы предпочел получить доступ к частной переменной, а не к публичному аксессуру «Возраст». Есть ли стандартная нотация для доступа к частной переменной, или это просто невозможно?

+10

В чем разница в этом случае доступа к частному и общедоступному аксессуару? Я считаю, что наилучшей практикой является доступ к публичному аксессуру даже из логики в объявляющем классе. Если вы когда-нибудь добавляете какую-то логику в аксессуар, вы не хотите менять весь свой код. –

+0

@ spoon16 Можете ли вы привести пример добавления логики к аксессуру и изменить код в результате. Я не совсем понял эту часть. – Ogen

ответ

2

Вы не можете, это функция языка, а не функция IDE. Честно говоря, я бы предпочел, чтобы IDE добавила для вас закрытую переменную. Я согласен с тем, что для класса достаточно странно использовать публичную точку входа для доступа к своим переменным. Поэтому я не использую эту новую функцию так много.

10

За кулисами, что происходит, является введение частной переменной-члена, с префиксом <> k__AutomaticallyGeneratedPropertyField #

От C# 3.0 Automatic Properties explained

Хотя это может быть возможным использовать этот частный элемент непосредственно, это очень хаки и ненужно.

12

Этот синтаксис обычно называется «синтаксическим сахаром», что означает, что компилятор принимает этот синтаксис и переводит его во что-то другое. В вашем примере, компилятор генерирует код, который выглядит примерно так:

[CompilerGenerated] 
private int <Age>k_BackingField; 

public int Age 
{ 
    [CompilerGenerated] 
    get 
    { 
     return this.<Age>k_BackingField; 
    } 
    [CompilerGenerated] 
    set 
    { 
     this.<Age>k_BackingField = value; 
    } 

Даже зная все, что вы могли бы вероятно доступ поле подложки непосредственно, но такого рода поражения цели использования автоматических свойств. Я говорю, вероятно, здесь, потому что тогда вы зависите от детали реализации, которая может измениться в любой момент в будущей версии компилятора C#.

23

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

Не используйте автоматические свойства, если у вас есть сложная логика в вашем классе. Просто зайдите private int _age и нормальные геттеры/сеттеры, как обычно.

IMO, автоматические свойства больше подходит для быстрого внедрения холостых объектов или временные капсул данных, как:

public class TempMessage { 
    public int FromID { get; set; } 
    public int ToID { get; set; } 
    public string Message { get; set; } 
} 

Где вам не нужны много логики.

+0

Почему добавление сложной логики в ваш класс влияет на использование автоматических свойств внутри этого класса? –

+0

Более сложная вещь ... если у вас сложная логика, тогда вы захотите получить к ней доступ из частной резервной переменной для каждой практики OO .. и если вы используете автоматические свойства, тогда ... будут возникать несоответствия в доступе к этим свойства. так как у некоторых будет символ подчеркивания, а некоторые - нет. – chakrit

92

Целью новых автоматических свойств является уменьшение количества кода шаблона, который необходимо написать, когда у вас просто есть свойство, которое не нуждается в какой-либо специальной логике в get или set.

Если вы хотите получить доступ к закрытому члену, что эти свойства используют, что, как правило, по нескольким причинам:

  • Вам нужно больше, чем просто получить/установить - в этом случае, вы должны просто избегать используя автоматические свойства для этого участника.
  • Вы хотите избежать хита производительности, проходящего через get или set, и просто использовать участника напрямую - в этом случае я был бы удивлен, если бы действительно был удар производительности. Простые элементы get/set очень просты в установке, и в моем (по общему признанию ограничении) тестировании я не нашел разницы между использованием автоматических свойств и доступом к элементу напрямую.
  • Вы хотите иметь доступ только к открытому доступу (т. Е. Просто «получить»), а класс писать непосредственно пользователю - в этом случае вы можете использовать частный набор в своем автоматическом свойстве. т.е.

    public class MyClass 
    { 
        public int Age {get; private set;} 
    }

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

+0

Правда - они уменьшают код котелок, и я также объявлю, что они уменьшают то, что вам нужно проверить. Некоторые могут утверждать, что вам нужно проверить инструкцию get/set, но не с авто свойствами, так как вы можете доверять структуре. –

+3

Образец кода здесь неправильный. Он должен быть общественный класс MyClass { public int Age {get; частный набор;} } Я согласен с этим ответом. Вы не можете получить доступ к частному полю, и если вам нужно, то вам не следует использовать автоматические свойства в первую очередь. – hwiechers

+0

hwiechers, спасибо за это - у меня было это редактирование, но при попытке исправить форматирование я, должно быть, снова нажал пасту и удалил неправильный блок кода. Doh! – Wilka

7

Вы не должны, и это очень маловероятно, что вам нужно. Если вам нужно получить доступ к свойству, просто используйте общедоступное свойство (например, this.Age). Нет ничего особенного в том, что частное поле поддерживает государственную собственность, используя его, предпочитая свойство, это просто суеверие.

+1

Я всегда задавался вопросом, какова точка автоматического свойства. Если у вас нет особой логики в ваших геттерах и сеттерах, зачем их вообще? –

+4

@MatthewLock гибкость. При прямом доступе к полю вы блокируетесь в этом проекте, если только вы не измените весь код клиента одновременно. Но если вы решите изменить его из «псевдополя» в вычисленное свойство, или если вы решите добавить утверждения и проверки на сеттер или что-то делать, вы можете сделать это прозрачно. Это еще более полезно, если вы пишете библиотечный код, где вы не можете контролировать весь код клиента. – Wedge