Зачем мне нужно "field:" в объявлении моего атрибута "[field:NonSerialized]"?
Я не могу найти "поле", указанное в качестве ключевого слова C#. Кто-нибудь знает предысторию этого?
5 ответов
Компилятор C# обычно без труда выясняет, к какой части объявления относится атрибут. Я могу вспомнить три случая, когда вы могли бы использовать его:
- Атрибуты, которые применяются к сборке. Очень хорошо видно в AssemblyInfo.cs
- Атрибут, примененный к возвращаемому значению объявления P/Invoke, [return:MarshalAs]
- Наличие атрибута применяется к резервной переменной свойства или события без средств доступа. Твой случай.
Это необходимо, например, если вы помечаете событие как не сериализуемое. Он указывает цель, к которой применяется атрибут.
Это часть целевого синтаксиса атрибута. Из спецификации:
attribute-target:
field
event
method
param
property
return
type
Смотрите также документацию для NonSerializedAttribute
:
Чтобы применить
NonSerializedAttribute
класс в событие, установите местоположение атрибута в поле, как показано в следующем коде C#.
[field:NonSerializedAttribute()]
public event ChangedEventHandler Changed;
Это позволяет вам устанавливать атрибут NonSerialized для полей, это полезно при сериализации событий.
Например, это даст вам ошибку компиляции
[NonSerialized]
public event SomeEventHandler SomeEvent;
Чтобы исправить это, вы должны использовать field:
[field:NonSerialized]
public event SomeEventHandler SomeEvent;
Подробнее об этом здесь - делегаты и сериализация
NonSerializedAttribute применим только к полям, вы можете использовать его следующим образом:
[NonSerialized]
public string myString;
На этот вопрос уже был дан ответ, но я подробно продемонстрирую случай автоматически реализуемых свойств.
[NonSerialized] применяется только к полям, поскольку он относится к средству двоичного форматирования, которое сериализует данные полей, в отличие от чего-то вроде Json.NET, который сериализует свойства.
[NonSerialized]
public int Value;
Мы не можем использовать его непосредственно для автоматически реализуемых свойств — следующее не компилируется:
[NonSerialized]
public int Value { get; set; }
Мы можем использовать модификатор «field:», чтобы применить атрибут к автоматически реализуемому резервному полю:
[field: NonSerialized]
public int Value { get; set; }
Что эквивалентно:
public int Value
{
get => backingField;
set => backingField = value;
}
[NonSerialized]
private int backingField;