В С#, что отличает поле от свойства, и когда следует использовать поле вместо свойства?
В чем разница между полем и свойством?
Ответ 1
Свойства выставляют поля. Поля должны (почти всегда) быть закрытыми для класса и доступны через свойства get и set. Свойства предоставляют уровень абстракции, позволяющий изменять поля, не влияя на внешний способ доступа к ним тем, что используют ваш класс.
public class MyClass
{
// this is a field. It is private to your class and stores the actual data.
private string _myField;
// this is a property. When accessed it uses the underlying field,
// but only exposes the contract, which will not be affected by the underlying field
public string MyProperty
{
get
{
return _myField;
}
set
{
_myField = value;
}
}
// This is an AutoProperty (C# 3.0 and higher) - which is a shorthand syntax
// used to generate a private field for you
public int AnotherProperty{get;set;}
}
@Kent указывает, что свойства не требуются для инкапсуляции полей, они могут выполнять вычисления в других полях или выполнять другие задачи.
@GSS указывает, что вы также можете выполнять другую логику, такую как проверка, когда доступ к ресурсу, другая полезная функция.
Ответ 2
Принципы ориентированного на объекты программирования говорят, что внутренние работы класса должны быть скрыты от внешнего мира. Если вы выставляете поле, вы по существу раскрываете внутреннюю реализацию класса. Поэтому мы обертываем поля с помощью свойств (или методов в случае Java), чтобы дать нам возможность изменять реализацию, не нарушая при этом код в зависимости от нас. Видя, что мы можем поместить логику в Свойство, мы также можем выполнить логику проверки и т.д., Если нам это нужно. С# 3 имеет, возможно, запутанное понятие autoproperties. Это позволяет нам просто определить свойство, а компилятор С# 3 будет генерировать для нас частное поле.
public class Person
{
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
public int Age{get;set;} //AutoProperty generates private field for us
}
Ответ 3
Важным отличием является то, что интерфейсы могут иметь свойства, но не поля. Это, как мне кажется, подчеркивает, что свойства должны использоваться для определения открытого класса класса, в то время как поля предназначены для использования в частных внутренних процессах класса. Как правило, я редко создаю публичные поля, и, как правило, я редко создаю непубличные свойства.
Ответ 4
Я дам вам пару примеров использования свойств, которые могут привести к переключению передач:
- Lazy Initialization : Если у вас есть свойство объекта, который загружается дорого, но он не имеет доступа ко всему, что имеет место в обычных прогонах кода, вы можете отложить его загрузку через свойство. Таким образом, он просто сидит там, но в первый раз, когда другой модуль пытается вызвать это свойство, он проверяет, является ли базовое поле нулевым - если оно есть, оно идет вперед и загружает его, неизвестное вызывающему модулю. Это может значительно ускорить инициализацию объекта.
- Грязное отслеживание: что я действительно узнал из моего собственного вопроса здесь, в StackOverflow. Когда у меня есть много объектов, значения которых могли быть изменены во время прогона, я могу использовать свойство для отслеживания необходимости их сохранения в базе данных или нет. Если ни одно свойство объекта не изменилось, флаг IsDirty не сработает, и поэтому функция сохранения пропустит его, решив, что нужно вернуть в базу данных.
Ответ 5
Используя свойства, вы можете выбросить событие, когда значение свойства изменится (иначе свойство PropertyChangedEvent) или до того, как значение будет изменено для поддержки отмены.
Это невозможно для полей (прямого доступа).
public class Person {
private string _name;
public event EventHandler NameChanging;
public event EventHandler NameChanged;
public string Name{
get
{
return _name;
}
set
{
OnNameChanging();
_name = value;
OnNameChanged();
}
}
private void OnNameChanging(){
EventHandler localEvent = NameChanging;
if (localEvent != null) {
localEvent(this,EventArgs.Empty);
}
}
private void OnNameChanged(){
EventHandler localEvent = NameChanged;
if (localEvent != null) {
localEvent(this,EventArgs.Empty);
}
}
}
Ответ 6
Поскольку многие из них объяснили с техническими плюсами и минусами Properties
и Field
, пришло время перейти к примерам в реальном времени.
1. Свойства позволяют установить уровень доступа только для чтения.
Рассмотрим случай dataTable.Rows.Count
и dataTable.Columns[i].Caption
. Они приходят из класса DataTable
и оба являются для нас публичными. Разница в уровне доступа к ним заключается в том, что мы не можем установить значение dataTable.Rows.Count
но мы можем читать и записывать в dataTable.Columns[i].Caption
. Это возможно через Field
? Нет !!! Это можно сделать только с помощью Properties
.
public class DataTable
{
public class Rows
{
private string _count;
// This Count will be accessable to us but have used only "get" ie, readonly
public int Count
{
get
{
return _count;
}
}
}
public class Columns
{
private string _caption;
// Used both "get" and "set" ie, readable and writable
public string Caption
{
get
{
return _caption;
}
set
{
_caption = value;
}
}
}
}
2. Свойства в PropertyGrid
Возможно, вы работали с Button
в Visual Studio. Его свойства отображаются в PropertyGrid
такие как " Text
, " Name
и т.д. Когда мы перетаскиваем кнопку и когда щелкаем свойства, она автоматически находит класс Button
и фильтрует Properties
показывая, что в PropertyGrid
(где PropertyGrid
не будет отображаться). Field
хоть они и публичные).
public class Button
{
private string _text;
private string _name;
private string _someProperty;
public string Text
{
get
{
return _text;
}
set
{
_text = value;
}
}
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
[Browsable(false)]
public string SomeProperty
{
get
{
return _someProperty;
}
set
{
_someProperty= value;
}
}
В PropertyGrid
будут отображаться свойства Name
и Text
, но не SomeProperty
. Зачем??? Потому что свойства могут принимать атрибуты. Не отображается в случае, если [Browsable(false)]
равно false.
3. Может выполнять операторы внутри свойств
public class Rows
{
private string _count;
public int Count
{
get
{
return CalculateNoOfRows();
}
}
public int CalculateNoOfRows()
{
// Calculation here and finally set the value to _count
return _count;
}
}
4. Только свойства могут быть использованы в Binding Source
Binding Source помогает нам уменьшить количество строк кода. Fields
не принимаются BindingSource
. Мы должны использовать Properties
для этого.
5. Режим отладки
Представьте, что мы используем Field
для хранения значения. В какой-то момент нам нужно отладить и проверить, где значение становится нулевым для этого поля. Это будет трудно сделать, когда число строк кода больше 1000. В таких ситуациях мы можем использовать Property
и установить режим отладки внутри Property
.
public string Name
{
// Can set debug mode inside get or set
get
{
return _name;
}
set
{
_name = value;
}
}
Ответ 7
РАЗЛИЧИЯ - ИСПОЛЬЗОВАНИЕ (когда и почему)
A поле - это переменная, которая объявляется непосредственно в классе или структуре. Класс или структура могут иметь поля экземпляра или статические поля или и то, и другое. Как правило, вы должны использовать поля только для переменных, которые имеют закрытую или защищенную доступность. Данные, которые ваш класс предоставляет клиенту, должны предоставляться с помощью методов, свойств и индексаторов. Используя эти конструкции для непрямого доступа к внутренним полям, вы можете защитить от недопустимых входных значений.
A свойство - это член, который предоставляет гибкий механизм для чтения, записи или вычисления значения частного поля. Свойства можно использовать так, как если бы они были публичными элементами данных, но на самом деле это специальные методы, называемые accessors. Это позволяет легко получать доступ к данным и все еще помогает повысить безопасность и гибкость методов. Свойства позволяют классу открывать общедоступный способ получения и установки значений, скрывая код реализации или проверки. Атрибут get get используется для возврата значения свойства, а для доступа к новому значению используется аксессуар набора.
Ответ 8
Свойства имеют основное преимущество, позволяя вам изменить способ доступа к данным на объекте, не нарушая его публичный интерфейс. Например, если вам нужно добавить дополнительную проверку или изменить сохраненное поле в вычисленном, вы можете сделать это легко, если вы первоначально выставили поле в качестве свойства. Если вы просто открыли поле напрямую, вам нужно будет изменить общедоступный интерфейс вашего класса, чтобы добавить новую функциональность. Это изменение приведет к поломке существующих клиентов, требуя их повторной компиляции, прежде чем они смогут использовать новую версию вашего кода.
Если вы пишете библиотеку классов, предназначенную для широкого потребления (например,.NET Framework, которая используется миллионами людей), это может быть проблемой. Однако, если вы пишете класс, используемый внутри внутри небольшой базы кода (например, строки = 50 K), это действительно не очень важно, потому что на ваши изменения вы не пострадали. В этом случае это действительно сводится к личным предпочтениям.
Ответ 9
В фоновом режиме свойство компилируется в методы. Таким образом, свойство Name
скомпилировано в get_Name()
и set_Name(string value)
. Вы можете это увидеть, если изучаете скомпилированный код.
Таким образом, при использовании их есть (очень) небольшие накладные расходы. Обычно вы всегда будете использовать свойство, если вы выставляете поле снаружи, и часто будете использовать его внутри, если вам нужно выполнить проверку значения.
Ответ 10
Свойства поддерживают асимметричный доступ, т.е. вы можете иметь либо геттер, и сеттер, либо только один из них. Аналогично свойства поддерживают индивидуальную доступность для геттера/сеттера. Поля всегда симметричны, т.е. Вы всегда можете получить и установить значение. Исключением для этого являются поля только для чтения, которые, очевидно, не могут быть установлены после инициализации.
Свойства могут работать очень долго, иметь побочные эффекты и даже исключать исключения. Поля быстрые, без побочных эффектов, и никогда не будут бросать исключения. Из-за побочных эффектов свойство может возвращать другое значение для каждого вызова (как это может быть в случае DateTime.Now, то есть DateTime.Now не всегда равно DateTime.Now). Поля всегда возвращают одно и то же значение.
Поля могут использоваться для параметров out/ref, свойства могут отсутствовать. Свойства поддерживают дополнительную логику - это может быть использовано для реализации ленивой загрузки между прочим.
Свойства поддерживают уровень абстракции, инкапсулируя все, что он означает, чтобы получить/установить значение.
Используйте свойства в большинстве/во всех случаях, но старайтесь избегать побочных эффектов.
Ответ 11
Если вы хотите, чтобы ваша личная переменная (поле) была доступна объекту вашего класса из других классов, вам нужно создать свойства для этих переменных.
например, если у меня есть переменные с именем "id" и "name", которые являются частными но может быть ситуация, когда эта переменная необходима для операции чтения/записи вне класса. В этой ситуации свойство может помочь мне получить эту переменную для чтения/записи в зависимости от get/set, определенного для свойства. Свойство может быть readonly/writeonly/readwrite.
вот демонстрация
class Employee
{
// Private Fields for Employee
private int id;
private string name;
//Property for id variable/field
public int EmployeeId
{
get
{
return id;
}
set
{
id = value;
}
}
//Property for name variable/field
public string EmployeeName
{
get
{
return name;
}
set
{
name = value;
}
}
}
class MyMain
{
public static void Main(string [] args)
{
Employee aEmployee = new Employee();
aEmployee.EmployeeId = 101;
aEmployee.EmployeeName = "Sundaran S";
}
}
Ответ 12
Второй вопрос здесь, "когда нужно использовать поле вместо свойства?", вкратце затрагивается в этом другом ответе и как-то этот тоже, но не очень подробно.
В общем, все остальные ответы находят о хорошем дизайне: предпочитают подвергать свойства более подверженным полям. В то время как вы, вероятно, не будете регулярно находить себя, говоря "ничего себе, представьте, насколько хуже было бы, если бы я сделал это поле вместо свойства", он так много реже думать о ситуации, когда вы скажете: "Вау, слава богу, я использовал здесь поле вместо собственности".
Но есть одно преимущество, которое поля имеют над свойствами, и что их способность использоваться как параметры "ref" / "out". Предположим, у вас есть метод со следующей подписью:
public void TransformPoint(ref double x, ref double y);
и предположим, что вы хотите использовать этот метод для преобразования массива, созданного следующим образом:
System.Windows.Point[] points = new Point[1000000];
Initialize(points);
Здесь я думаю, что это самый быстрый способ сделать это, поскольку X и Y являются свойствами:
for (int i = 0; i < points.Length; i++)
{
double x = points[i].X;
double y = points[i].Y;
TransformPoint(ref x, ref y);
points[i].X = x;
points[i].Y = y;
}
И это будет очень хорошо! Если у вас нет измерений, которые доказывают обратное, нет причин бросать вонь. Но я считаю, что технически не гарантировано так быстро, как это:
internal struct MyPoint
{
internal double X;
internal double Y;
}
// ...
MyPoint[] points = new MyPoint[1000000];
Initialize(points);
// ...
for (int i = 0; i < points.Length; i++)
{
TransformPoint(ref points[i].X, ref points[i].Y);
}
Выполняя некоторые измерения, версия с поля занимает около 61% времени в качестве версии со свойствами (.NET 4.6, Windows 7, x64, режим деблокирования, без отладчика). Чем дороже метод TransformPoint
, тем менее выражен тот факт, что разница становится. Чтобы повторить это самостоятельно, запустите с отключенной первой строкой и с ней не закомментируйте.
Даже если для вышеизложенного не было преимуществ в производительности, есть и другие места, где возможность использования параметров ref и out может быть полезной, например, при вызове Interlocked или Volatile семейство методов. Примечание. Если это вам не знакомо, Volatile - это, в основном, способ получить то же поведение, что и ключевое слово volatile
. Как таковой, как volatile
, он не волшебным образом решает все проблемы, связанные с безопасностью потоков, такие как его имя, что он может.
Я определенно не хочу казаться, что я сторонник того, что вы идете "о, я должен начать выставлять поля вместо свойств". Дело в том, что если вам нужно регулярно использовать эти члены в вызовах, которые принимают параметры "ref" или "out", особенно на том, что может быть простым типом значения, который вряд ли когда-либо понадобится для добавления элементов свойств с добавленной стоимостью, можно сделать аргумент.
Ответ 13
Если вы собираетесь использовать примитивы потоков, вы вынуждены использовать поля. Свойства могут разбивать ваш код с резьбой. Кроме того, то, что сказал кори, является правильным.
Ответ 14
Кроме того, свойства позволяют использовать логику при настройке значений.
Итак, вы можете сказать, что хотите установить значение только в целочисленное поле, если значение больше, чем x, иначе выведите исключение.
Действительно полезная функция.
Ответ 15
(Это должен быть комментарий, но я не могу оставлять комментарии, поэтому, пожалуйста, извините, если это не подходит для публикации).
Я когда-то работал в месте, где рекомендуемая практика заключалась в использовании открытых полей вместо свойств, когда эквивалентное свойство def просто обращалось к полю, как в:
get { return _afield; }
set { _afield = value; }
Их аргументация заключалась в том, что публичное поле может быть преобразовано в собственность позже в будущем, если потребуется. В то время мне было немного странно. Судя по этим сообщениям, похоже, что здесь не многие согласятся. Что вы могли сказать, чтобы попытаться изменить ситуацию?
Изменить: я должен добавить, что вся база кода в этом месте была скомпилирована в одно и то же время, поэтому они могли подумать, что изменение открытого интерфейса классов (путем изменения открытого поля на свойство) не было проблемой,
Ответ 16
Технически я не думаю, что есть разница, потому что свойства - это всего лишь обертки вокруг полей, созданных пользователем или автоматически создаваемые компилятором. Целью свойств является принудительная инкапсуляция и предоставление легкого метода особенность. Это просто плохая практика объявлять поля общедоступными, но у нее нет никаких проблем.
Ответ 17
На этой странице в MSDN есть сравнение и советы по использованию, когда:
https://msdn.microsoft.com/en-us/library/9d65as2e(v=vs.90).aspx
Ответ 18
Поля обычные переменные-члены или экземпляры-члены класса. Свойства - это абстракция , чтобы получить и установить их значения. Свойства также называются аксессуарами, потому что они предлагают способ изменения и получения поля, если вы открываете поле в классе как личное. Как правило, вы должны объявлять свои переменные-члены private, а затем объявлять или определять для них свойства.
class SomeClass
{
int numbera; //Field
//Property
public static int numbera { get; set;}
}
Ответ 19
Свойства инкапсулируют поля, что позволяет выполнять дополнительную обработку значения, которое нужно установить или получить. Как правило, чрезмерное использование свойств, если вы не будете делать предварительную или постобработку по значению поля.
Ответ 20
IMO, Свойства - это только те пары функций/методов/интерфейсов SetXXX() "GetXXX()", которые мы использовали ранее, но они более сжатые и элегантные.
Ответ 21
Традиционно частные поля устанавливаются с помощью методов getter и setter. Для меньшего кода вы можете использовать свойства для установки полей.
Ответ 22
когда у вас есть класс, который является "Автомобилем". Свойства - это цвет, форма.
Где в качестве полей находятся переменные, определенные в рамках класса.
Ответ 23
Из Википедии - Объектно-ориентированное программирование:
Объектно-ориентированное программирование (ООП) - это парадигма программирования, основанная на понятии "объекты", которые представляют собой структуры данных, содержащие данные в виде полей, часто называемых атрибутами; и , в виде процедур, часто известных как методы. (выделено мной)
Свойства на самом деле являются частью поведения объекта, но предназначены для предоставления потребителям объекта иллюзии/абстракции работы с данными объекта.
Ответ 24
Мой дизайн поля заключается в том, что поле должно быть изменено только его родителем, а значит, и классом. Результат переменная становится частной, а затем, чтобы иметь возможность читать классы/методы за пределами, я просматриваю систему свойств только с помощью Get. Затем поле извлекается собственностью и доступно только для чтения! Если вы хотите его изменить, вам нужно пройти через методы (например, конструктор), и я обнаружил, что благодаря этому способу обеспечения безопасности мы лучше контролируем наш код, потому что мы "фланцем". Можно было бы всегда всегда ставить все на всеобщее обозрение, так что каждый возможный случай, понятие переменных/методов/классов и т.д.... на мой взгляд, просто помогает развитию, поддержанию кода. Например, если человек возобновляет код с публичными полями, он может делать что угодно и, следовательно, вещи "нелогичны" по отношению к объекту, логика написания кода. Это моя точка зрения.
Когда я использую классические модели private field/public readonly properties, для 10 приватных полей я должен написать 10 свойств публики! Код может быть действительно большим. Я открываю частный сеттер, и теперь я использую только публичные свойства с помощью частного сеттера. Создатель создает в фоновом режиме приватное поле.
Вот почему мой старый классический стиль программирования:
public class MyClass
{
private int _id;
public int ID { get { return _id; } }
public MyClass(int id)
{
_id = id;
}
}
Мой новый стиль программирования:
public class MyClass
{
public int ID { get; private set; }
public MyClass(int id)
{
ID = id;
}
}
Ответ 25
Поля - это переменные в классах. Поля - это данные, которые вы можете инкапсулировать с помощью модификаторов доступа.
Свойства похожи на поля в том, что они определяют состояния и данные, связанные с объектом.
В отличие от поля свойство имеет специальный синтаксис, который контролирует, как человек читает данные и записывает данные, они известны как операторы get и set. Заданная логика часто может использоваться для проверки.
Ответ 26
Свойства - это особый тип члена класса. В свойствах мы используем предопределенный метод Set или Get. Они используют аксессоры, через которые мы можем читать, писать или изменять значения частных полей.
Например, возьмем класс с именем Employee
с частными полями для имени, возраста и Employee_Id. Мы не можем получить доступ к этим полям вне класса, но мы можем получить доступ к этим приватным полям через свойства.
Почему мы используем свойства?
Создание поля класса публичным и подверженным экспонату является рискованным, так как вы не будете контролировать то, что назначается и возвращается.
Чтобы понять это с помощью примера, возьмите класс ученика, у которого есть ID, паспорт, имя. Теперь в этом примере проблема с открытым полем
- ID не должен быть -ve.
- Имя не может быть установлено в значение null
- Знак прохода следует читать только.
- Если имя ученика отсутствует, имя не должно быть возвращено.
Чтобы устранить эту проблему, мы используем метод Get и set.
// A simple example
public class student
{
public int ID;
public int passmark;
public string name;
}
public class Program
{
public static void Main(string[] args)
{
student s1 = new student();
s1.ID = -101; // here ID can't be -ve
s1.Name = null ; // here Name can't be null
}
}
Теперь мы возьмем пример метода get и set
public class student
{
private int _ID;
private int _passmark;
private string_name ;
// for id property
public void SetID(int ID)
{
if(ID<=0)
{
throw new exception("student ID should be greater then 0");
}
this._ID = ID;
}
public int getID()
{
return_ID;
}
}
public class programme
{
public static void main()
{
student s1 = new student ();
s1.SetID(101);
}
// Like this we also can use for Name property
public void SetName(string Name)
{
if(string.IsNullOrEmpty(Name))
{
throw new exeception("name can not be null");
}
this._Name = Name;
}
public string GetName()
{
if( string.IsNullOrEmpty(This.Name))
{
return "No Name";
}
else
{
return this._name;
}
}
// Like this we also can use for Passmark property
public int Getpassmark()
{
return this._passmark;
}
}
Ответ 27
Свойства используются для отображения поля. Они используют accessors (set, get), через которые могут считываться, записываться или обрабатываться значения частных полей.
В свойствах не указаны места хранения. Вместо этого у них есть аксессоры, которые читают, записывают или вычисляют свои значения.
Используя свойства, мы можем установить проверку на тип данных, заданных в поле.
Например, у нас есть частный возраст целочисленного поля, на котором мы должны допускать положительные значения, поскольку возраст не может быть отрицательным.
Мы можем сделать это двумя способами, используя getter и seters и используя свойство.
Using Getter and Setter
// field
private int _age;
// setter
public void set(int age){
if (age <=0)
throw new Exception();
this._age = age;
}
// getter
public int get (){
return this._age;
}
Now using property we can do the same thing. In the value is a key word
private int _age;
public int Age{
get{
return this._age;
}
set{
if (value <= 0)
throw new Exception()
}
}
Авто Реализованное свойство, если мы не используем логику в get и set accessors, мы можем использовать автоматически реализованное свойство.
Когда u se автоматически реализованные компиляции свойств создает личное, анонимное поле, доступ к которому можно получить только через get и set accessors.
public int Age{get;set;}
Абстрактные свойства Абстрактный класс может иметь абстрактное свойство, которое должно быть реализовано в производном классе
public abstract class Person
{
public abstract string Name
{
get;
set;
}
public abstract int Age
{
get;
set;
}
}
// overriden something like this
// Declare a Name property of type string:
public override string Name
{
get
{
return name;
}
set
{
name = value;
}
}
Мы можем частным образом установить свойство В этом случае мы можем частным образом установить свойство auto (задано в классе)
public int MyProperty
{
get; private set;
}
Вы можете добиться этого с помощью этого кода. В этой функции свойств свойство недоступно, так как мы должны напрямую установить значение в поле.
private int myProperty;
public int MyProperty
{
get { return myProperty; }
}
Ответ 28
Подумайте об этом: у вас есть комната и дверь, чтобы войти в эту комнату. Если вы хотите проверить, как кто приходит и защищает вашу комнату, тогда вы должны использовать свойства, иначе они не будут никакой дверью, и каждый может легко войти без каких-либо правил.
class Room {
public string sectionOne;
public string sectionTwo;
}
Room r = new Room();
r.sectionOne = "enter";
Люди вступают в sectionOne довольно легко, не было никакой проверки
class Room
{
private string sectionOne;
private string sectionTwo;
public string SectionOne
{
get
{
return sectionOne;
}
set
{
sectionOne = Check(value);
}
}
}
Room r = new Room();
r.SectionOne = "enter";
Теперь вы проверили человека и узнали, есть ли у него что-то злое с ним
Ответ 29
В подавляющем большинстве случаев это будет имя свойства, к которому вы обращаетесь, в отличие от имени переменной (field). Причина этого - это хорошая практика в .NET и С# в особенно для защиты каждой части данных внутри класса, будь то переменная экземпляра или статическая переменная (переменная класса), поскольку она связана с классом.
Защитите все эти переменные соответствующими свойствами, которые позволят вам определить установить и получить accessors и сделать такие вещи, как проверка, когда вы манипулируете этими фрагментами данных.
Но в других случаях, таких как Math class (пространство имен систем), существует несколько статических свойств, встроенных в класс. одна из которых является постоянной math PI
например. Math.PI
и поскольку PI - это четкая часть данных, нам не нужно иметь несколько копий PI, это всегда будет одинаковое значение. Поэтому статические переменные иногда используются для обмена данными между объектом класса, но они также обычно используются для постоянной информации, где вам нужна только одна копия части данных.
Ответ 30
Дополнительная информация: По умолчанию get и set accessors доступны так же, как и само свойство. Вы можете контролировать/ограничивать доступ к доступу индивидуально (для получения и установки), применяя на них более ограничивающие модификаторы доступа.
Пример:
public string Name
{
get
{
return name;
}
protected set
{
name = value;
}
}
Здесь get по-прежнему доступен для общего доступа (поскольку это свойство является общедоступным), но набор защищен (более ограниченный спецификатор доступа).