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

Когда использовать свойства и методы?

Я новичок в мире .NET из С++, и я пытаюсь лучше понять свойства. Я заметил, что в .NET Framework Microsoft использует свойства повсюду. Есть ли преимущество в использовании свойств, а не в создании методов get/set? Существует ли общее правило (а также соглашение об именах), когда нужно использовать свойства?

4b9b3361

Ответ 1

Это чистый синтаксический сахар. На обратной стороне он скомпилирован в простые методы get и set.

Используйте его из-за соглашения и что он выглядит лучше.

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

Ответ 2

Свойства - это методы get/set; просто они формализуют их в единую концепцию (для чтения и записи), позволяя (например) метаданные в отношении свойства , а не отдельных членов. Например:

[XmlAttribute("foo")]
public string Name {get;set;}

Это пара методов get/set, но дополнительные метаданные применяются к обоим. Кроме того, IMO просто упрощает использование:

someObj.Name = "Fred"; // clearly a "set"
DateTime dob = someObj.DateOfBirth; // clearly a "get"

Мы не дублировали тот факт, что мы делаем get/set.

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

Ответ 3

Существует целая книга, посвященная ответам на такие вопросы: Принципы разработки рамок от Addison-Wesley. См. Раздел 5.1.3 для консультаций о том, когда следует выбирать свойство по сравнению с методом.

Большая часть содержимого этой книги также доступна на MSDN, но я считаю ее удобной иметь на своем столе.

Ответ 5

свойствами являются методы get/set

Ответ 6

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

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

Я лично считаю, что основная идея свойств.

Ответ 7

Я всегда считаю, что свойства - существительные класса, где методы - это глаголы...

Ответ 8

Прежде всего, соглашение об именах: используйте имя PascalCase для имени свойства, как и методы. Кроме того, свойства не должны содержать очень сложные операции. Это должно быть сделано в методах.

В ООП вы бы описали объект как имеющий атрибуты и функциональность. Вы делаете это при разработке класса. Рассмотрим проектирование автомобиля. Примерами функциональности могут быть способность перемещаться где-то или активировать стеклоочистители. В вашем классе это были бы методы. Атрибутом будет количество пассажиров в автомобиле в данный момент. Без свойств у вас есть два способа реализовать атрибут:

Сделать переменную общедоступной:

// class Car
public int passengerCount = 4;

// calling code
int count = myCar.passengerCount;

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

Второй вариант - один используемый для использования, e. г. в Java, где у вас нет свойств, подобных в С#:

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

// class Car
public int GetPassengerCount()
{
   // perform some operation
   int result = CountAllPassengers();

   // return the result
   return result;
}

// calling code
int count = myCar.GetPassengerCount();

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

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

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

EDIT: Я почти забыл упомянуть об этом: способность выполнять определенные проверки перед тем, как задать переменную. Просто используя общедоступную переменную, вы можете в принципе писать что-нибудь в нее. Метод или свойство setter дает вам возможность проверить его до его фактического сохранения.

Ответ 9

Свойства просто избавят вас от написания шаблона, который идет вместе с методами get/set.

При этом многие элементы .NET обрабатывают свойства по-разному - например, Grid автоматически отображает свойства, но не отображает функцию, которая делает эквивалент.

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

Ответ 10

Компилятор фактически испускает методы get_MyProperty и set_MyProperty для каждого определяемого вами свойства.

Ответ 11

Хотя это не является жестким и быстрым правилом, и, как указывали другие, свойства реализуются как пары "Get/Set" "за кулисами" - как правило, свойства данных с инкапсулированными/защищенными свойствами поверхности, тогда как методы (ака процедуры или функции) работать и давать результат этой работы.

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

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

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

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

Ответ 12

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

Ответ 13

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

Ответ 14

Свойства - это не просто синтаксический сахар - они важны, если вам нужно создать объектно-реляционные сопоставления (Linq2Sql или Linq2Entities), поскольку они ведут себя как переменные, в то время как можно скрыть детали реализации объектно-реляционного сопоставления (persistance). Также возможно проверить значение, присвоенное ему в getter свойства, и защитить его от присвоения нежелательных значений.

Вы не можете сделать это с такой же элегантностью с помощью методов. Я думаю, что лучше продемонстрировать это на практическом примере.

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

public class Product
{
    [Key]
    public int ProductID { get; set; }

    public string ProductName { get; set; }
    public Decimal? UnitPrice { get; set; }
    public bool Discontinued { get; set; }
    public virtual Category category { get; set; }
}

// class Category omitted in this example

public class Northwind : DbContext
{
    public DbSet<Product> Products { get; set; }
    public DbSet<Category> Categories { get; set; }
}

Вы можете использовать наборы сущностей Products, Categories и связанные классы Product и Category так же, как если бы они были нормальными объектами, содержащими переменные: вы можете читать и писать их, и они ведут себя точно так же, как и обычные переменные. Но вы также можете использовать их в запросах Linq, сохраняйте их (храните их в базе данных и извлекайте их). Примечание также, как легко использовать annotations (атрибуты С#) для определения первичного ключа (в этом примере ProductID является первичным ключом для Product).

В то время как свойства используются для определения представления данных, хранящихся в базе данных, существуют некоторые методы, определенные в классе объектов > , которые контролируют постоянство: например, метод Remove() отмечает данный объект как удаленный, а Add() добавляет данный объект, SaveChanges() делает изменения постоянными. Вы можете рассматривать методы как действия (т.е. Вы управляете тем, что хотите делать с данными).

Наконец, я даю вам пример того, как естественно вы можете использовать эти классы:

// instantiate the database as object
var nw = new NorthWind();

// select product
var product = nw.Products.Single(p => p.ProductName == "Chai");

// 1. modify the price
product.UnitPrice = 2.33M;

// 2. store a new category
var c = new Category();
c.Category = "Example category";
c.Description = "Show how to persist data";
nw.Categories.Add(c);

// Save changes (1. and 2.) to the Northwind database
nw.SaveChanges();