These two attributes are used for opposite sides of the serialization equation.
When you use [NonSerialized]
, you're saying "this field should not be serialized at all" - so it's more of a "save time" attribute. Basically, you're saying that field does not matter for the serialized state of the object.
When you use [OptionalField]
, on the other hand, you're still going to serialize the field. However, if the field is missing at read time (when the stream is deserialized into an object), then no exception will be raised. This attribute is really intended to allow you to add a new field to an existing serializable type, without breaking compatibility. Older versions of the object (which are missing that field) will be deserialized normally.