Есть ли причина использовать автоматически реализуемые свойства вместо свойств, реализованных вручную?

Я понимаю преимущества PROPERTIES перед FIELDS, но мне кажется, что использование AUTO-реализуемых свойств над MANUAL-реализуемыми свойствами на самом деле не дает никаких преимуществ, кроме как сделать код немного более лаконичным для его просмотра.

Мне гораздо удобнее пользоваться:

    private string _postalCode;

    public string PostalCode
    {
        get { return _postalCode; }
        set { _postalCode = value; }
    }

Вместо:

public string PostalCode { get; set; }

в первую очередь потому, что если я когда-либо захочу выполнить какую-либо индивидуальную реализацию get и set, мне все равно придется создать собственное свойство, подкрепленное частным полем. Так почему бы просто не бросить курить с самого начала и сразу придать всем свойствам гибкость для единообразия? На самом деле это займет всего одну секунду, учитывая, что все, что вам нужно сделать в Visual Studio, - это щелкнуть имя личного поля и нажать Ctrl + E, и все готово. И если я сделаю это вручную, то я получу несогласованность, в которой есть НЕКОТОРЫЕ вручную созданные общедоступные свойства, поддерживаемые частными полями, и НЕКОТОРЫЕ автоматически реализованные свойства. Я чувствую себя намного лучше, когда он во всех отношениях постоянен, либо полностью автоматический, либо полностью ручной.

Это только я? Я что-то упускаю? Я в чем-то ошибаюсь? Неужели я слишком много внимания уделяю последовательности? Я всегда могу найти законные дискуссии о возможностях C #, и почти всегда есть свои плюсы и минусы, но в этом случае я действительно не смог найти никого, кто бы рекомендовал использовать автоматически реализуемые свойства.


person CptSupermrkt    schedule 14.11.2011    source источник
comment
Вы говорите, что можете сделать это сейчас, потому что в будущем вам might придется это сделать. Зачем тратить время на то, что подвержено ошибкам (вы, вероятно, все равно будете копировать и вставлять), если вы можете делать это только тогда, когда это необходимо?   -  person Rob    schedule 14.11.2011
comment
Спасибо, Роб. Я считаю, что с помощью Visual Studio я могу создавать вручную реализованные свойства с помощью всего одного дополнительного нажатия клавиши, поэтому копирование / вставка не выполняется. И если когда-нибудь мне действительно понадобится создать свою собственную реализацию, у меня не будет разрыва между автоматически реализуемыми свойствами и свойствами, реализуемыми вручную, это на 100% одно или на 100% другое. Просто полностью перейдя на ручной режим с самого начала, я могу создать свою собственную реализацию в любое время без автоматической реализации некоторых свойств, а некоторые свойства - вручную. Хотя я определенно понимаю вашу точку зрения.   -  person CptSupermrkt    schedule 14.11.2011
comment
В этом случае я с вами, придерживаясь 100% ручной реализации. Я склонен к предвзятости после того, как натолкнулся на множество опечаток с ручными геттерами / сеттерами.   -  person Rob    schedule 14.11.2011
comment
в VS 2010 (по крайней мере) вы можете ввести prop и нажать вкладку. Это приводит к автоматически реализуемому свойству.   -  person cwharris    schedule 14.11.2011
comment
Самым большим преимуществом является экономия времени на чтение / отладку.   -  person n00dles    schedule 03.11.2015


Ответы (7)


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

Одним из преимуществ использования auto props является то, что он потенциально может спасти вас от глупой ошибки кодирования, такой как случайное присвоение неправильной частной переменной свойству. Поверьте, я делал это раньше!

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

person Ryan Berger    schedule 14.11.2011
comment
По моему опыту, общедоступные объекты лишают людей представления о ООП. В проекте, над которым я сейчас работаю, есть объекты, у которых только некоторые свойства инициализируются некоторое время, поэтому можно догадываться, имеет ли это свойство значение NULL или нет, и в кодовой базе есть много областей, которые проверяют наличие NULL. Я думаю, что они отлично подходят для некоторых случаев, в случае, который я выделил, они кажутся дьяволом. - person CodyEngel; 18.03.2015
comment
@CodyEngel нет гарантии, что объект, к которому осуществляется доступ через метод доступа, также не равен нулю. Если люди будут писать неаккуратный код со свойствами, они будут писать небрежный код без. - person iheanyi; 27.07.2017

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

Это очень маловероятно, но это серьезная проблема, если вы пытаетесь сохранить возможность «заменять» версию ваших сборок на более новые версии.

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

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

person cwharris    schedule 14.11.2011

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

person ChrisWue    schedule 14.11.2011
comment
Ах, так где-то там была дискуссия по этому поводу :) Спасибо за ссылку! - person CptSupermrkt; 14.11.2011

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

Забыл: если вы или какой-либо продукт, который вы используете, выполняет рефлексию на членах (например, WCF), вы увидите искаженное имя резервного поля вместо созданного вами "красивого" резервного поля.

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

Еще немного пояснений: предположим, что у вас есть веб-служба, которая предоставляет некоторые из ваших бизнес-объектов через WCF для созданного вами клиента silverlight. Чтобы повторно использовать вашу бизнес-логику, ваш клиент Silverlight добавляет ссылки на исходный код для ваших бизнес-объектов. Если у вас есть автоматически реализованные свойства, вы не можете управлять именем резервного поля. Поскольку WCF сериализует члены, а не свойства, вы не можете быть уверены, что объект, переданный в silverlight из службы WCF, будет десериализоваться правильно, потому что имена поддерживающих полей почти наверняка будут несовместимы.

person competent_tech    schedule 14.11.2011

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

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

Когда мне нужно поле поддержки, мне нужно сделать паузу два раза, это немного замедляет разработку :)

Я делаю это так:

  1. Сделайте это частной переменной в начале
  2. При необходимости измените его публично автоматически.
  3. Измените его на поле поддержки, если мне нужен какой-то код в get или set.

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

person parapura rajkumar    schedule 14.11.2011

Одно из преимуществ использования автоматических свойств, которое я вижу: при отладке приложения оно не переходит в ненужный раздел Get / Set. Я знаю, что этого можно избежать, используя атрибуты отладчика или переход; однако в большинстве случаев это происходит при отладке большого приложения.

person Riju    schedule 14.11.2011

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

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

  • Есть ли прирост производительности или поражение при использовании одного способа по сравнению с другим?

Подобно тому, как выяснять, сколько движений нужно, чтобы добраться до центра Tootsie Roll Tootsie Pop, я решил: «давай узнаем».

Давайте сначала действительно сравним яблоки с яблоками.

Предположим, у нас есть два класса:

public class C 
{
    private int z;
    public int Z
    {
        get { return z;}
    }
}

public class Q
{
    public int Z { get; }
}

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

Давайте посмотрим на IL, сгенерированный для каждого.

Во-первых, версия ручного резервного хранилища:

// Fields
.field private int32 z

// Methods
.method public hidebysig specialname 
    instance int32 get_Z () cil managed 
{
    // Method begins at RVA 0x2050
    // Code size 12 (0xc)
    .maxstack 1
    .locals init (
        [0] int32
    )

    IL_0000: nop
    IL_0001: ldarg.0
    IL_0002: ldfld int32 C::z
    IL_0007: stloc.0
    IL_0008: br.s IL_000a

    IL_000a: ldloc.0
    IL_000b: ret
} // end of method C::get_Z

.method public hidebysig specialname rtspecialname 
    instance void .ctor () cil managed 
{
    // Method begins at RVA 0x2068
    // Code size 8 (0x8)
    .maxstack 8

    IL_0000: ldarg.0
    IL_0001: call instance void [System.Private.CoreLib]System.Object::.ctor()
    IL_0006: nop
    IL_0007: ret
} // end of method C::.ctor

// Properties
.property instance int32 Z()
{
    .get instance int32 C::get_Z()
}

Теперь посмотрим на IL для второго класса:

// Fields
.field private initonly int32 '<Z>k__BackingField'
.custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
    01 00 00 00
)
.custom instance void [System.Private.CoreLib]System.Diagnostics.DebuggerBrowsableAttribute::.ctor(valuetype [System.Private.CoreLib]System.Diagnostics.DebuggerBrowsableState) = (
    01 00 00 00 00 00 00 00
)

// Methods
.method public hidebysig specialname 
    instance int32 get_Z () cil managed 
{
    .custom instance void [System.Private.CoreLib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
        01 00 00 00
    )
    // Method begins at RVA 0x2071
    // Code size 7 (0x7)
    .maxstack 8

    IL_0000: ldarg.0
    IL_0001: ldfld int32 Q::'<Z>k__BackingField'
    IL_0006: ret
} // end of method Q::get_Z

.method public hidebysig specialname rtspecialname 
    instance void .ctor () cil managed 
{
    // Method begins at RVA 0x2068
    // Code size 8 (0x8)
    .maxstack 8

    IL_0000: ldarg.0
    IL_0001: call instance void [System.Private.CoreLib]System.Object::.ctor()
    IL_0006: nop
    IL_0007: ret
} // end of method Q::.ctor

// Properties
.property instance int32 Z()
{
    .get instance int32 Q::get_Z()
}

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

Вы можете возразить, что на ваш вопрос нет ответа, но подумайте ...

Если вы когда-либо кодировали свойства, участвующие в привязке, например:

    private string name;
    public string Name 
    { 
        get { return name; }
        set { SetProperty (ref name, value);
    }

Тогда резервный магазин - это то, что вам нужно.

С другой стороны, использование ярлыка "prop" ‹TAB> ‹TAB> в редакторе Visual Studio для создания автоматических свойств просто супер удобно и намного быстрее, чем all что печатать;)

Так что в итоге для молотка все похоже на гвоздь. Не будь молотком.

person Stacy Dudovitz    schedule 31.10.2019