2009-12-02 2 views
10

мой вопрос прост, использует ли свойства get C# считаться хорошим, лучше, чем писать методы getter и setter? Когда вы используете эти свойства, вам не нужно объявлять своих членов данных класса общедоступными? Я спрашиваю об этом, потому что мой профессор заявил, что члены данных должны никогда не объявлять, поскольку это считается плохой практикой.Является ли использование get set свойствами C# считается хорошей практикой?

Это ....

class GetSetExample 
{ 
    public int someInt { get; set; } 
} 

против это ...

class NonGetSetExample 
{ 
    private int someInt; 
} 

Edit:

Спасибо всем вам! Все ваши ответы помогли мне, и я, соответственно, проголосовал за ваши ответы.

+0

Это на самом деле то, о чем мы просим, ​​когда мы даем интервью новым приложениям. Зачем вам использовать первый за второй :-) –

+0

Профессора должны быть достаточно умны, чтобы знать, что не использовать абсолюты! Если он не переопределит «никогда», значит «не без понимания и принятия возможных последствий» ... –

ответ

14

Это:

class GetSetExample 
{ 
    public int someInt { get; set; } 
} 

действительно так же, как это:

class GetSetExample 
{ 
    private int _someInt; 
    public int someInt { 
     get { return _someInt; } 
     set { _someInt = value; } 
    } 
} 

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

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

4

В вашем первом примере C# автоматически генерирует частные поля поддержки, поэтому технически член данных не объявляется публичным только получателем/установщиком.

+0

Технически, но это совершенно бессмысленное различие. –

+8

Не совсем. Свойства могут использоваться в других областях, тогда как методы или поля не могут. Автоматическое связывание приходит на ум. –

+7

В некоторых ситуациях это очень важно. Если вы объявляете общедоступную переменную, вы застряли в том, что являетесь общедоступной переменной, если вы не хотите изменить ABI на эту сборку.С помощью {get; задавать; } public, все общедоступные доступы происходят через методы доступа, поэтому вы можете изменить методы доступа, чтобы впоследствии иметь разные функции, не заставляя всех перекомпилировать свои приложения, ссылающиеся на вашу сборку. –

0

Это вполне разумно, и ваш профессор (без контекста) ошибается. Но в любом случае, используя «автоматические свойства», все в порядке, и вы можете сделать это независимо от того, являются ли они публичными или частными.

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

+1

Я бы предположил, что контекст будет Java (или, возможно, C++), поскольку Java не имеет свойств как C#. – FrustratedWithFormsDesigner

+0

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

+0

Читая эти ответы, я немного чувствую себя в зоне сумерек. –

7

Да, члены, как правило, никогда не должны быть объявлены публичными в хорошем дизайне по нескольким причинам. Подумайте о OOP, где вы наследуете класс позже. Вид трудно переопределить поле. :-) Также он не позволяет вам напрямую обращаться к вашим внутренним лицам.

Упрощенный get; задавать; дизайн был введен в C# 2.0. Это в основном то же самое, что декларировать все с помощью частного участника, поддерживающего его (декомпилируйте его в инструменте, таком как Reflector, и посмотрите).

public int someInt{get;set;} 

непосредственно равна

private int m_someInt; 
public int someInt{ 
    get { return m_someInt; } 
    set { m_someInt = value; } 
} 

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

Не беспокойтесь о том, что геттер/сеттеры замедляют ваш код с помощью косвенности. У JIT есть вещь, называемая inlineing, которая использует метод getter/setter так же эффективно, как и прямой доступ к полям.

+1

Согласен. Учитывая длинную в реальном времени библиотеку .NET. Чтобы сохранить его, вы должны быть очень осторожны, прежде чем подвергать что-то внешнему миру, и большую часть времени вы должны выставлять свойство вместо поля. Это самый безопасный способ, как в будущих версиях, вы можете свободно изменять реализацию этого свойства, не причиняя вреда вызывающим сборкам. Что произойдет, если вы откроете поле напрямую? Это должен быть бесконечный кошмар, так как вы никогда не сможете его изменить. –

1

В «чистом» объектно-ориентированном подходе не считается полностью открытым состояние объектов, и это относится к свойствам, поскольку они реализованы в .NET и get_ set_ properteis Java/EJB. Идея состоит в том, что, обнажая состояние вашего объекта, вы создаете внешние зависимости для внутреннего представления данных вашего объекта. Конструкция чистого объекта уменьшает все взаимодействия с сообщениями с параметрами.

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

7

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

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

0

Ваш профессор был совершенно прав.

Рассмотрим этот тривиальный пример того, почему «добытчиками» следует избегать: Там может быть 1000 вызовов метода getX() в вашей программе, и каждый из этих вызовов предполагает, что возвращаемое значение определенного типа. Возвращаемое значение getX() может быть указано в локальной переменной, например, и тип переменной должен соответствовать типу возвращаемого значения. Если вам нужно изменить способ реализации объекта таким образом, чтобы изменились тип X, у вас большие проблемы. Если X было int, но теперь должно быть long, теперь вы получите 1000 ошибок компиляции. Если вы устраните проблему неправильно, отбросив возвращаемое значение до int, код будет скомпилирован, но не будет работать. (Возвращаемое значение может быть усечено.) Вы должны изменить код, окружающий каждую из этих 1000 вызовов, чтобы компенсировать изменение. Я, по крайней мере, не хочу делать такую ​​работу.

Holub On Patterns

+0

Это не имеет никакого смысла в контексте вопроса. Какая альтернатива? Никогда не позволяйте кому-либо избрать члена класса? – Sterno

+0

Sterno: Ну, даже его профессор, кажется, так говорит («мой профессор заявил, что члены данных никогда не должны объявляться публичными»). почему это плохо, чтобы объявлять члены данных общедоступными, но писать больше кода для * точно такого же эффекта * нормально? –

+0

Я согласен с тем, что сказал его профессор. Я просто не думаю, что то, что вы цитируете, имеет большой смысл в практическом применении. Такие инструменты, как Resharper, делают изменение типа переменной довольно тривиальным и даже если вы не используете getter/setter. метод, это не значит, что вы избежите связанной боли с изменением типа свойства. Поэтому, пока я возвращаю то, что сказал его профессор, я не думаю, что эта цитата делает многое, чтобы поддержать аргумент. – Sterno

1

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

public MyVar{private get; public set;} 

означает значение MyVar может быть изменено только внутри класса и может быть считан из класса (читать в частном порядке и читать публично), и это не является р ossible только с публичными данными

+0

Новый совет пользователя: Не очень полезно добавить ответ на очень старый вопрос, когда на этот вопрос уже есть куча ответов. – hyde

Смежные вопросы