Когда использовать свойства и методы? - PullRequest
12 голосов
/ 31 июля 2009

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

Ответы [ 14 ]

12 голосов
/ 31 июля 2009

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

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

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

7 голосов
/ 31 июля 2009

Свойства являются методами 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.

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

6 голосов
/ 31 июля 2009

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

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

4 голосов
/ 31 июля 2009

Подумайте о прочтении Выбор между свойствами и методами . В нем много информации о рекомендациях по проектированию .NET.

2 голосов
/ 31 июля 2009

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

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

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

// class Car
public int passengerCount = 4;

// calling code
int count = myCar.passengerCount;

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

Второй вариант - это один использованный видли, т.е. г. в Java, где у вас нет свойств, как в c #:

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

// 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: Я почти забыл упомянуть об этом: возможность на самом деле выполнять определенные проверки, прежде чем позволить переменной быть установленной. Просто используя открытую переменную, вы можете в нее записать что угодно. Метод или свойство установщика дает вам возможность проверить его перед его сохранением.

2 голосов
/ 31 июля 2009

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

2 голосов
/ 31 июля 2009

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

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

Лично я думаю, что это основная идея свойств.

2 голосов
/ 31 июля 2009

свойства методы get / set

1 голос
/ 31 июля 2009

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

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

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

0 голосов
/ 18 апреля 2013

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

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

В одной из своих статей Скотт Гу создает классы, которые сопоставляются с базой данных 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, сохранять их (сохранять в базе данных и извлекать их). Обратите внимание также, насколько просто использовать аннотации (атрибуты C #) для определения первичного ключа (в этом примере 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();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...