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

Можно ли принудительно использовать свойство auto-property для использования поля для чтения в режиме readonly?

В моем проекте содержится большое количество классов со свойствами, чье фоновое поле отмечено только как указано только при построении. Что касается стиля, мне нравится использовать авто-свойства, так как он устраняет много кода шаблона и поощряет использование свойства, а не поля поддержки. Однако при использовании авто-собственности я теряю "readonly-ness" моего поля поддержки. Я понимаю, что компилятор/среда выполнения может воспользоваться некоторыми улучшениями производительности, когда поле помечено таким образом, поэтому я хотел бы отметить, что мое авто-свойство можно читать как-то так:

[ReadOnly]
public string LastName { get; }

а не

private readonly string _LastName;
public string LastName 
{ 
    get
    { 
        return _LastName;
    }
}

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

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

public readonly string LastName;
4b9b3361

Ответ 1

Я боюсь, что нет, но вы можете это сделать:

public string LastName { get; private set; }

Не так хорошо, как readonly, но не так уж плохо.

Ответ 2

Нет, к сожалению, нет способа сделать это. Лично есть две вещи, которые, как мне кажется, отсутствуют в автоматически реализованных свойствах в С# - значение по умолчанию (которое, как я полагаю, будет в VB10) и свойства readonly, которые могут быть установлены только в конструкторе. Другими словами, я хотел бы иметь возможность:

public class Foo
{
    public string Tag { get; internal set; } = "Default value";

    // The "readonly" would imply "private" as it could only
    // be set from a constructor in the same class
    public int Value { get; readonly set; }

    public Foo()
    {
        // Valid to set property here, but nowhere else
        Value = 20;
    }
}

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

Это упростит запись неизменяемых типов. К сожалению, ситуация не улучшится на С# 4. Пусть надеемся, что мы получим что-то вроде этого для С# 5...

Ответ 3

Нет, это не так, и если бы эта функция была бесполезной без существенной настройки.

Поле readonly может быть проверено только с помощью конструктора. Автореализованное свойство может быть установлено только из сгенерированного сеттера. Это несовместимые требования и выдаст непроверяемый код.

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

Foo() {
  SomeProperty = "somevalue";
}

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

ИЗМЕНИТЬ

Это не говорит, что это невозможно сделать. Это может, но для С# потребуется немного работы.

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

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

Я не говорю, что любой из них - хорошие варианты, просто возможности сделать этот тип работы.

Ответ 4

Как и на С# 6.0, ответ да. Ваш пример можно записать, как показано ниже, и компилятор автоматически генерирует только поле для чтения за свойством. Это называется авто-свойство только для геттера.

public string LastName { get; }

Из https://msdn.microsoft.com/en-us/magazine/dn879355.aspx

Авто-свойства Getter-only доступны как в структурах, так и в классе декларации, но особенно важны для структур из-за руководящие принципы лучшей практики, которые могут быть неизменными. Вместо шесть или около того строк, необходимых для объявления свойства только для чтения и инициализации это до С# 6.0, теперь однострочное объявление и присвоение изнутри конструктора все, что нужно. Таким образом, декларация неизменяемых структур теперь не только правильный шаблон программирования для структур, но и более простой шаблон - очень ценное изменение из предыдущего синтаксиса, где правильное кодирование потребовало больших усилий.

Ответ 5

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

Ответ 6

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