Почему я должен избегать использования свойств в C #? - PullRequest
100 голосов
/ 29 марта 2009

В своей превосходной книге CLR Via C # Джеффри Рихтер сказал, что ему не нравятся свойства, и рекомендует не использовать их. Он привел причину, но я не совсем понимаю. Может кто-нибудь объяснить мне, почему я должен или не должен использовать свойства? В C # 3.0 с автоматическими свойствами это меняется?

В качестве ссылки я добавил мнение Джеффри Рихтера:

• Свойство может быть доступно только для чтения или только для записи; доступ к полю всегда читабелен и доступен для записи. Если вы определяете свойство, лучше всего предлагать методы доступа как get, так и set.

• Метод свойства может вызвать исключение; доступ к полю никогда не вызывает исключение.

• Свойство не может быть передано как параметр out или ref в метод; поле может. За Например, следующий код не будет компилироваться:

using System;
public sealed class SomeType
{
   private static String Name 
   {
     get { return null; }
     set {}
   }
   static void MethodWithOutParam(out String n) { n = null; }
   public static void Main()
   {
      // For the line of code below, the C# compiler emits the following:
      // error CS0206: A property or indexer may not
      // be passed as an out or ref parameter
      MethodWithOutParam(out Name);
   }
}

• Метод свойства может занять много времени; Доступ к полю всегда завершается немедленно. Распространенной причиной использования свойств является синхронизация потоков, которая может остановить поток навсегда, и, следовательно, свойство не должно использоваться, если синхронизация потока необходимо. В этой ситуации метод является предпочтительным. Кроме того, если ваш класс может быть удаленный доступ (например, ваш класс является производным от System.MashalByRefObject), вызов метода свойства будет очень медленным, и поэтому метод предпочтительнее имущество. По моему мнению, классы, производные от MarshalByRefObject, никогда не должны использовать свойства.

• Если вызывается несколько раз подряд, метод свойства может возвращать разные значения каждый время; поле возвращает одно и то же значение каждый раз. Класс System.DateTime имеет только для чтения Теперь свойство, которое возвращает текущую дату и время. Каждый раз, когда вы запрашиваете это свойство, он вернет другое значение. Это ошибка, и Microsoft желает, чтобы они можно исправить класс, сделав метод Now вместо свойства.

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

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

Ответы [ 14 ]

4 голосов
/ 10 апреля 2009

Есть время, когда я считаю, что не нужно использовать свойства, и это при написании кода .Net Compact Framework. JIT-компилятор CF не выполняет ту же оптимизацию, что и JIT-компилятор рабочего стола, и не оптимизирует простые средства доступа к свойствам, поэтому в этом случае добавление простого свойства вызывает небольшое увеличение объема кода по сравнению с использованием открытого поля. Обычно это не является проблемой, но почти всегда в мире Compact Framework вы сталкиваетесь с жесткими ограничениями памяти, поэтому даже крошечная экономия, как эта, имеет значение.

3 голосов
/ 23 марта 2018

Аргумент предполагает, что свойства плохие, потому что они выглядят как поля, но могут выполнять неожиданные действия. Это предположение опровергается ожиданиями программистов .NET:

Свойства не похожи на поля. Поля выглядят как свойства.

• Метод свойства может вызвать исключение; доступ к полю никогда не вызывает исключение.

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

• Свойство не может быть передано как параметр out или ref в метод; поле может.

Итак, поле похоже на свойство, но у него есть дополнительные возможности: переход к ref / out принимающим методам.

• Метод свойства может занять много времени; Доступ к полю всегда завершается немедленно. [...]

Итак, поле похоже на быстрое свойство.

• Если вызывается несколько раз подряд, метод свойства может каждый раз возвращать другое значение; поле возвращает одно и то же значение каждый раз. Класс System.DateTime имеет свойство Now только для чтения, которое возвращает текущую дату и время.

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

• Метод свойств может вызывать наблюдаемые побочные эффекты; доступ к полю никогда не делает.

Опять же, поле - это свойство, которое гарантированно этого не сделает.

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

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

3 голосов
/ 29 марта 2009

Лично я использую свойства только при создании простых методов get / set. Я отхожу от этого, когда подхожу к сложным структурам данных.

0 голосов
/ 13 сентября 2013

Вызов методов вместо свойств значительно снижает читаемость вызывающего кода. Например, в J # использование ADO.NET было кошмаром, потому что Java не поддерживает свойства и индексаторы (которые по сути являются свойствами с аргументами). Результирующий код был очень уродливым, с пустыми скобками, вызывающими методы повсюду.

Поддержка свойств и индексаторов является одним из основных преимуществ C # перед Java.

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