Why do I need "field:" in my attribute declaration "[field:NonSerialized]"?
Asked Answered
D

5

19

I can't find "field" listed as a C# keyword anywhere. Does anyone know the background on this?

Dorrie answered 7/1, 2010 at 16:57 Comment(2)
Can you post a little bit more code? Where are you trying to create a new attribute, or are you applying the attribute somewhere. More context would help.Cloud
I forgot about those. I've updated my list of C# keywords to include them. Thanks! See blogs.msdn.com/ericlippert/archive/2009/05/11/… for details.Kashakashden
F
8

The C# compiler usually has no trouble figuring out what part of a declaration the attribute applies to. I can think of three cases where you might use it:

  1. Attributes that apply to the assembly. Very visible in AssemblyInfo.cs
  2. An attribute applied to the return value of a P/Invoke declaration, [return:MarshalAs]
  3. Having the attribute apply to the backing variable of a property or event without accessors. Your case.
Fissure answered 7/1, 2010 at 18:15 Comment(0)
L
15

This is necessary, for example, if you are marking an event as non-serializable. It specifies the target that the attribute applies to.

It is part of the attribute target syntax. From the specification:

attribute-target:
    field
    event
    method
    param
    property
    return
    type

See also the documentation for NonSerializedAttribute:

To apply the NonSerializedAttribute class to an event, set the attribute location to field, as shown in the following C# code.

[field:NonSerializedAttribute()]

public event ChangedEventHandler Changed;

Livy answered 7/1, 2010 at 17:2 Comment(7)
Well you can't serialize an event, and the NonSerializedAttribute is only applicable to fields, so I don't understand what [field:NonSerializedAttribute()] does, I'm also surprised it compiles.Inartificial
The point is that objects that subscribe to the event will be considered as part of the object graph and serialized when the object containing the event is serialized. To prevent them as being serialized you have to attribute the event with the NonSerializedAttribute. But as NonSerializedAttribute only applies to fields, you have to mark it with the attribute-target field.Livy
Yuriy, I believe that delegates are compiled into classes, in which case when its serialized it they serialize with their invocation list. In this case you need to set it as [NonSerialized] however it throws a compile error, so you need to specify field:NonSerialized. I think they fixed it in .NET 3.5 howeverDiscus
@Jason I just used an XML Serializer and the event wasn't serialized.Inartificial
I can see how the EventHandler class is marked as Serializable, how can I reproduce this behavior for an event?Inartificial
Odd, "assembly" is missing. The important one.Fissure
@nobugz: They are handled differently as part of the non-terminal global-attributes. Specifically, global-attribute-target: assembly module.Livy
F
8

The C# compiler usually has no trouble figuring out what part of a declaration the attribute applies to. I can think of three cases where you might use it:

  1. Attributes that apply to the assembly. Very visible in AssemblyInfo.cs
  2. An attribute applied to the return value of a P/Invoke declaration, [return:MarshalAs]
  3. Having the attribute apply to the backing variable of a property or event without accessors. Your case.
Fissure answered 7/1, 2010 at 18:15 Comment(0)
D
5

This is meant to allow you to set NonSerialized attribute on fields, this is useful in serializing events.

For instance this would give you a compilation error

[NonSerialized]
public event SomeEventHandler SomeEvent;

To fix this you have to use field:

[field:NonSerialized]
public event SomeEventHandler SomeEvent;

More on this here -- Delegates and Serialization

Discus answered 7/1, 2010 at 17:10 Comment(4)
But you're marking it as NonSerialized, and events can't be serialized.Inartificial
Yuriy, I believe in .NET 3.0 events/delegates were serializable as classes, so you had to specify them as NonSerializedDiscus
Yuriy, please take a look at the following link msdn.microsoft.com/en-us/magazine/cc163902.aspx#S1Discus
You are correct. I was using the XmlSerializer to serialize the class, which doesn't have event serialization. But the BinaryFormatter is fine with it.Inartificial
O
1

This has already been answered but I demonstrate explicitly the case for auto-implemented properties.

[NonSerialized] applies only to fields, because it relates to the binary formatter which serializes field data as opposed to something like Json.NET which serializes properties.

[NonSerialized]
public int Value;

We cannot use it directly on auto-implemented properties - the following does not compile:

[NonSerialized]             
public int Value { get; set; }

We can use the "field:" modifier to apply the attribute to the auto-implemented backing field:

[field: NonSerialized]
public int Value { get; set; }

Which is equivalent to:

public int Value 
{ 
    get => backingField;
    set => backingField = value;
}

[NonSerialized]
private int backingField;
Orest answered 27/4, 2023 at 12:43 Comment(0)
I
0

The NonSerializedAttribute is only applicable to fields, you can use it as follows:

[NonSerialized]
public string myString;
Inartificial answered 7/1, 2010 at 17:2 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.