У меня есть путаница в понимании свойства и переменных
public class ABC()
{
public int A;
public int B { get; set; }
}
Какая разница между A и B?
У меня есть путаница в понимании свойства и переменных
public class ABC()
{
public int A;
public int B { get; set; }
}
Какая разница между A и B?
Как указывали многие, A - поле, B - свойство.
Реальный вопрос: зачем вам это нужно и что использовать?
Я ссылаюсь на сообщение блога Джонатана Анеи:
(Его в VB, но это относится и к С#;))
Итак, зачем использовать свойства над полями, 5 причин:
1. Поля не могут использоваться в интерфейсах
Вы не можете обеспечить существование поле в публичном контракте объектов через интерфейс. Для свойств хотя он отлично работает.
2. Проверка
Пока ваше приложение может не требуется какая-либо логика проверки установить определенное значение, изменив бизнес-требованиям может потребоваться добавив эту логику позже. При этом точка смены поля на свойство является изменением для потребителей ваш API. (Например, если кто-то был проверяя ваш класс с помощью отражения).
3. Двоичная сериализация
Изменение поля для свойства - это если вы используете двоичный код сериализации. Кстати, это одна из причин VB10s автоматически реализованные свойства имеют "привязываемое" фоновое поле (т.е. вы можете выразить имя поля поддержки в коде) - таким образом, если вы измените автоматически реализованное свойство расширенное свойство, вы все равно можете поддерживать совместимость с сериализацией путем сохранения имени поля поддержки то же самое (в С# вы вынуждены его менять потому что он генерирует поддерживающие поля с непередаваемыми именами).
4. Большая часть инфраструктуры привязки данных .NET привязывается к свойствам, но не к полям
Ive услышал аргументы с обеих сторон, как для того, хорошо это или нет, но реальность такова, как это работает прямо сейчас. (Отметьте меня: привязки WPF работают над свойствами)
5. Выявление открытого поля - Нарушение FxCop
По многим причинам, перечисленным выше:)
Там может быть больше причин.
Я также хотел бы указать на сообщение в блоге Джеффа Этвуда и завершить цитату из него:
Очень важно убрать здесь, чтобы избежать написания кода, который не имеет значения. И оболочки свойств вокруг общедоступных переменных являются самой сутью бессмысленного кода.
A - поле, B - свойство. Свойство - это в основном синтаксический сахар для геттеров и сеттеров. Определенный вами класс будет скомпилирован примерно так:
public class ABC()
{
public int A;
private int backing_B;
public void set_B(int value)
{
backing_B = value;
}
public int get_B()
{
return backing_B;
}
}
Обратите внимание, что такой тип преобразования справедлив для всех свойств С# - обращения к ABC.B будут преобразованы в вызовы методов. Свойства в основном обеспечивают иллюзию "переменной", а на самом деле просто умственно замаскированную пару методов.
Это важно, потому что он позволяет вам объявить свой собственный метод get и set method, который может проверять значения или делать другие интересные вещи:
private int b;
public int B {
get { return b; }
set {
if (value < 0) throw new ArgumentOutOfRangeException("value");
b = value;
}
}
Обратите внимание, что большинство свойств будут использовать поле для хранения своего значения. Свойства редко существуют сами по себе, кроме полей.
Свойство - это своего рода короткий геттер и/или сеттер. Вы можете добавить логику в свойство set
или get
свойства или сделать их закрытыми, что означает, что они недоступны извне, где переменная всегда доступна (если она общедоступна).
Переменная - это переменная.
Свойство - это особый тип метода, который предоставляет эту переменную. И поскольку это метод, поэтому вы можете делать с ним другие вещи, кроме как подвергать переменную переменную.
Из MSDN:
В заявлении Property вводится объявление свойства. Свойство может иметь процедуру Get (только чтение), процедуру Set (только запись) или оба (чтение и запись). Вы можете опустить процедуру Get и Set при использовании автоматически реализованного свойства. Дополнительные сведения см. В разделе "Автоматически реализованные свойства" (Visual Basic).
Вы можете использовать свойство только на уровне класса. Это означает, что контекст объявления для свойства должен быть классом, структурой, модулем или интерфейсом и не может быть исходным файлом, пространством имен, процедурой или блоком. Дополнительные сведения см. В разделе "Контексты декларации" и "Уровни доступа по умолчанию".
По умолчанию свойства используют открытый доступ. Вы можете настроить уровень доступа к свойствам с помощью модификатора доступа в операторе Property, и вы можете дополнительно настроить одну из своих процедур свойств на более ограничительный уровень доступа.
В С# любая "переменная", имеющая геттер и сеттер, называется свойством. У переменной нет геттеров и сеттеров или так, что говорят в текстовых книгах.
Мой инструктор по программированию заставил нас иметь геттеры и сеттеры для почти каждой переменной, которую мы создали на Java. Даже индексирующие переменные он заставил нас использовать getter и setter, если они были объявлены в области глобального класса. Я думаю, что это, возможно, было чрезмерным, но это заставило меня создавать геттеры и сеттеры.
Реальные вещи о геттерах и сеттерах заключаются в том, что они более чем вероятно делают больше, чем просто устанавливают внутреннюю переменную. Большинство сеттеров собираются выполнить некоторый тип проверки данных, чтобы убедиться, что данные могут быть установлены в переменную. Геттер также может проверять возвращаемые данные по некоторым критериям.
Если ваше свойство является приватным, а ваши сеттеры и получатели доступны публично, любой человек может получить доступ к вашей переменной и изменить ее, как если бы у них был открытый доступ к фактической переменной. Таким образом, в действительности вы должны проверить свои данные, чтобы убедиться, что они действительны или некоторые другие проверки данных.
private int myVariable;
public int myVariable
{
get
{
return myVariable;
}
set
{
if (value < 0)
{
throw new Exception("This is your exception some where else in code");
}
myVariable = value; //remember value is something that is
//declared automatically
}
}
public string FirstName { get; set; }
Вышеупомянутый способ - записать следующий
private string firstName;
public string FirstName
{
get
{
//...code here
}
set
{
//...code here
}
}
В вашем примере A
является общедоступным полем класса ABC
и B
является общедоступным свойством класса ABC
. В частности, B
является автоматически реализованным свойством. Это означает, что "под капотом" компилятор выполняет определенную работу для вас и эффективно преобразует ваш код в:
public class ABC()
{
private int b;
public int A;
public int B
{
get
{
return b;
}
set
{
b = value;
}
}
}
Переменная определяется в основном для доступа к значению из класса или в тот же класс в соответствии с их модификатором, назначенным этой переменной.
Когда мы определяем свойство, создаются два метода для одного свойства, поэтому генерируются дополнительные служебные данные, что является недостатком свойства.
Преимущества свойств - получить или установить значение в закрытую переменную класса.
Существует очень хорошая статья (ссылка ниже) об использовании полей/переменных vs Properties из самой Microsoft. Хотя статья в основном говорит о правиле нарушения FxCop, она четко определяет разницу между двумя и точными правилами использования.
Выдержка из статьи:
Основное использование поля должно быть как деталь реализации. Поля должны быть частными или внутренними и должны быть открыты с использованием свойств. Доступ к объекту так же просто, как доступ к полю, и код в аксессуарах свойств может измениться по мере расширения функций типа без внесения изменений.
См. Https://docs.microsoft.com/en-us/previous-versions/dotnet/netframework-3.0/ms182141(v=vs.80)
Вы можете установить только чтение для свойств, только объявив get fnc для свойства. Но мы не можем делать это с переменной.
- BinhPT -