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

Свойства и поля: нужна помощь в использовании свойств над полями

Во-первых, я прочитал список сообщений по этой теме, и я не чувствую, что у меня хватало свойства из-за того, что я понял, что касается инкапсуляции и модификаторов полей (private, public..ect).

Одним из основных аспектов С#, который я пришел узнать, является важность защиты данных в вашем коде с помощью инкапсуляции. Я подумал: "Я понял, что это связано с возможностью использования модификаторов (private, public, internal, protected). Однако, узнав о свойствах, я как бы разорван в понимании не только свойств, но и общей важности/способности защиты данных (что я понял как инкапсуляция) в С#.

Чтобы быть более конкретным, все, что я прочитал, когда получил свойства в С#, заключается в том, что вы должны попытаться использовать их вместо полей, когда сможете, из-за:

1) они позволяют вам изменять тип данных, когда вы не можете напрямую обращаться к полю.

2) они добавляют уровень защиты доступа к данным

Однако из того, что я "думал", что я узнал об использовании модификаторов полей, сделал №2, мне показалось, что свойства только что сгенерировали дополнительный код, если у вас не было причин менять тип (# 1) - потому что вы (более или менее) создаете скрытые методы для доступа к полям, а не напрямую.

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

Я прочитал несколько глав разных авторов о "свойствах", и ни один из них не объяснил хорошее понимание свойств и полей против инкапсуляции (и хороших методов программирования).

Может кто-нибудь объяснить:

1), почему я хотел бы использовать свойства вместо полей (особенно когда он появляется, я просто добавляю дополнительный код

2) любые советы по распознаванию использования свойств и не видя их в виде простых методов (за исключением того, что get: set быть очевидным) при отслеживании кода других людей?

3) Любые общие правила, когда дело доходит до хороших методов программирования относительно того, когда использовать что?

Спасибо и извините за длинный пост - я не хотел просто задавать вопрос, который был задан 100x, не объясняя, почему я спрашиваю его снова.

4b9b3361

Ответ 1

Вам не следует беспокоиться о дополнительном коде, который необходим для доступа к полям через свойства, он будет "оптимизирован" компилятором JIT (путем вложения кода). За исключением случаев, когда он слишком велик, чтобы быть встроенным, но тогда вам нужен дополнительный код.

И дополнительный код для определения простых свойств также минимален:

public int MyProp { get; set; } // use auto generated field.

Когда вам нужно настроить, вы можете в дальнейшем определить свое собственное поле позже.

Итак, вы остаетесь с дополнительным слоем инкапсуляции/защиты данных, и это хорошо.

Мое правило: всегда открывать поля по свойствам

Ответ 2

1) почему я хотел бы использовать свойства вместо полей (особенно когда это Я просто добавляю дополнительные код

Вы всегда должны использовать свойства, где это возможно. Они абстрагируют прямой доступ к полю (который создается для вас, если вы его не создаете). Даже если свойство ничего не делает, кроме установки значения, оно может защитить вас позже. Изменение поля для свойства позже является нарушением изменений, поэтому, если у вас есть общедоступное поле и вы хотите изменить его на общедоступное свойство, вам необходимо перекомпилировать весь код, который первоначально обращался к этому полю.

2) любые советы по признанию использования свойства и не видя их как просто методы (за исключением получить, установить очевидное), когда отслеживание кода других людей?

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

3) Любые общие правила, когда это приходит к хорошим методам программирования в отношение к тому, когда использовать что?

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

Ответ 3

Одна из приятных вещей о свойствах заключается в том, что получатель и сеттер могут иметь разные уровни доступа. Рассмотрим это:

public class MyClass {

  public string MyString { get; private set; }

  //...other code
}

Это свойство может быть изменено только внутри, например, в конструкторе. Прочтите информацию об инъекции зависимостей. Инъекция конструктора и инъекция свойств связаны с настройкой свойств из некоторой формы внешней конфигурации. Там много фреймворков. Если вы углубитесь в некоторые из них, вы получите хорошее представление о свойствах и их использовании. Инъекция зависимости также поможет вам с 3-м вопросом о хорошей практике.

При взгляде на код других людей вы можете определить, является ли что-то методом или свойством, потому что их значки разные. Кроме того, в Intellisence первой частью сводки свойств является слово Property.

Ответ 4

1) Существует несколько причин, по которым вы можете использовать свойства над полями, вот только пара:

a) Имея следующее

public string MyProperty { get; private set; }

вы делаете свойство "только для чтения". Никто, использующий ваш код, не может изменить его значение. Бывают случаи, когда это не совсем верно (если ваше свойство является списком), но они известны и имеют решения.

b) Если вы решите, что вам необходимо повысить безопасность ваших свойств использования кода:

public string MyProperty
{
    get { return _myField; }
    set
    {
        if (!string.IsNullOrEmpty(value))
        {
            _myField = value;
        }
    }
}

2) Вы можете сказать, что они являются свойствами, потому что у них нет (). Компилятор скажет вам, если вы попытаетесь добавить скобки.

3). Считалось, что хорошая практика всегда использует свойства.

Ответ 5

В то время как я абсолютно не люблю напрямую разоблачать поля для общественности, есть еще одна вещь: поля не могут быть открыты через интерфейсы; Свойства могут быть.

Ответ 6

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

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

Ответ 7

why I would want to use properties instead of fields (especially when it appears I am just adding additional code

Вы хотите использовать свойства по полям, потому что, когда вы используете свойства, вы можете использовать с ними события, поэтому в случае, когда вы хотите выполнить какое-либо действие при изменении свойства, вы можете связать некоторые обработчики с событиями PropertyChanging или PropertyChanged. В случае полей это невозможно. Поля могут быть общедоступными или частными или защищенными, в случае реквизита вы можете сделать их доступными только для чтения публично, но пишите в конфиденциальном режиме.

any tips on recognizing the use of properties and not seeing them as simply methods (with the exception of the get;set being apparent) when tracing other peoples code?

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

Any general rules of thumb when it comes to good programming methods in relation to when to use what?

Да, я настоятельно рекомендую прочитать Руководство по разработке каркаса для лучших практик хорошего программирования.

Ответ 8

Использование полей обычно практикуется в частных классах, которые не предназначены для совместного использования данных с другими классами. Когда мы хотим, чтобы наши данные были доступны другим классам, мы используем свойства, которые имеют возможность обмениваться данными с другими классами через get и set, которые являются методами доступа, называемыми Auto Properties, которые имеют доступ к данным в частных классах, также вы можете использовать оба с модификаторами доступа в одном классе, позволяя классу использовать данные в частном порядке в качестве поля данных и в то же время связывать private для свойства, которое делает данные доступными для других классов, см. этот простой пример:

private string _name;  
public string Name    
{
   get
     {
       return _name;
     }
   set
     {
      _name = value;
     }
}

Частная строка _name используется только классом, а свойство Name доступно другими классами в одном и том же пространстве имен.

Ответ 9

Я собирался сказать, что Свойства (сеттеры) - отличное место для того, чтобы поднимать события, такие как NotifyPropertyChanged, но кто-то другой избил меня.

Еще одна веская причина для рассмотрения свойств: скажем, вы используете фабрику для создания какого-либо объекта, у которого есть конструктор по умолчанию, и вы готовите объект через свои Свойства.

new foo(){Prop1 = "bar", Prop2 = 33, ...};

Но если внешние пользователи обновляют свой объект, возможно, есть некоторые свойства, которые вы хотите, чтобы они отображались как доступные только для чтения и не могли установить (только фабрика должна иметь возможность их устанавливать)? Вы можете сделать сеттеры внутренними - это работает, конечно, если класс объекта находится в той же сборке, что и фабрика.

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

Ответ 10

Одно предостережение в том, что такие вещи, как "Threading.Interlocked.Increment", могут работать с полями, но не могут работать со свойствами. Если два потока одновременно называют Threading.Interlocked.Increment на SomeObject.LongIntegerField, значение увеличивается на два, даже если нет другой блокировки. В отличие от этого, если два потока одновременно называют Threading.Interlocked.Increment на SomeObject.LongIntegerProperty, значение этого свойства может увеличиваться на два или на один или на -4 294 967 295 или кто знает, какие другие значения (свойство может быть записано для использования блокировки в этом сценарии запрещены значения, отличные от одного или двух, но он не может быть записан для обеспечения правильного приращения на два).

Ответ 11

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

При взгляде на код других людей свойства имеют разные значки intellisense для методов.

Если вы считаете, что свойства - это всего лишь дополнительный код, я бы все равно придерживался их, но упростил вашу жизнь, автоматически создавая свойство из поля (щелкните правой кнопкой мыши → Refactor → Encapsulate Field...)

Ответ 12

Свойства позволяют выполнять другие действия, кроме как устанавливать или получать значение при их использовании. Прежде всего, они позволяют вам выполнять логику проверки.

Лучшая практика заключается в том, чтобы сделать что-либо открытым для общественности. Таким образом, если вы измените логику set/get в более позднее время, вам придется перекомпилировать свой класс, а не каждый класс, связанный с ним.