Почему свойства атрибутов должны быть читабельными? - PullRequest
15 голосов
/ 30 сентября 2011

Рассмотрим следующий атрибут.

internal class NiceAttribute : Attribute
{
  private string _stuff;

  public string Stuff
  {
    set { _stuff = value; }
  }
}

Когда я пытаюсь использовать атрибут [Nice(Stuff = "test")], компилятор выдает следующую ошибку.

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


Обновление
Я попытаюсь набросать свой сценарий использования свойств только для записи для атрибутов.

interface ISettingsBuilder
{
  Settings GetSettings();
}

class SettingsAttribute : Attribute, ISettingsBuilder
{
  private readonly IDictionary<string, object> _settings =
    new Dictionary<string, object>();

  public Settings GetSettings()
  {
    // Use _settings to create an immutable instance of Settings
  }

  public string Stuff
  {
    set { _settings["Stuff"] = value; }
  }

  // More properties ...
}

Могут быть и другие реализации ISettingsBuilder.Например, тот, который предлагает хороший API для создания настроек с помощью кода.

Я закончил реализацию своих методов получения, бросив NotImplementedException.

  public string Stuff
  {
    get { throw new NotImplementedException(); }
    set { _settings["Stuff"] = value; }
  }

Можете ли вы придумать лучший способсделать что-то подобное?

Ответы [ 2 ]

7 голосов
/ 30 сентября 2011

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

Редактировать"мы" теперь нашли фактическуюисточник.Для ознакомления, здесь приведена полная разбивка, но не стесняйтесь переходить ко дну. (обратите внимание, как следует сообщать об ошибке в Mono-компиляторе. Я подумаю над этим некоторое время)

Ошибка компилятора CS0617

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

Была сделана попытка доступа к закрытому члену класса атрибута.

Может показаться , что он использует какой-то поиск (сродни отражению), чтобы убедиться, что getter доступен и если это не такТаким образом, приходит к выводу, что это должно быть частным .

Что, конечно, не должно быть:)

Mono Совместимость:

Ради интереса, обратите внимание, что у моно-компилятора нет проблем с принятием этого атрибута: https://ideone.com/45fCX

Из-за отражения:

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

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

Обновление @Arunопубликовал соответствующую цитату, которая подтверждает эту гипотезу (спасибо!):

Доступ к атрибутам с помощью отражения После того, как атрибуты были связаны с элементами программы, отражение может бытьиспользуется для запроса их существования и ценностей.Основные методы отражения для запроса атрибутов содержатся в классе System.Reflection.MemberInfo (семейство методов GetCustomAttributes).

Таким образом, причина должна быть: Параметры атрибута должны иметь отражающие значения

Призовой вопрос: Какчто работает с позиционными параметрами?Как можно отразить это?

3 голосов
/ 30 сентября 2011

Эта ссылка является ссылкой из Visual Studio 2003, но, думаю, она почти не изменилась.

Соответствующая часть по этой ссылке:

Доступ к атрибутам через отражение После того, как атрибуты были связаны с элементами программы, можно использовать отражение для запроса их существования и значений. Основные методы отражения для запроса атрибутов содержатся в классе System.Reflection.MemberInfo (семейство методов GetCustomAttributes).

...