反序列化后初始化私有只读字段

And*_*ris 12 c# initialization private readonly deserialization

我需要在反序列化后初始化私有只读字段.我有以下DataContract:

[DataContract]
public class Item
{
    public Item()
    {
        // Constructor not called at Deserialization 
        // because of FormatterServices.GetUninitializedObject is used
        // so field will not be initialized by constructor at Deserialization
        _privateReadonlyField = new object();
    }

    // Initialization will not be called at Deserialization (same reason as for constructor)
    private readonly object _privateReadonlyField = new object();

    [DataMember]
    public string SomeSerializableProperty { get; set; }

    [OnDeserializing]
    public void OnDeserializing(StreamingContext context)
    {
        // With this line code even not compiles, since readonly fields can be initialized only in constructor
        _privateReadonlyField = new object();
    }
}
Run Code Online (Sandbox Code Playgroud)

所有我需要的,在反序列化后_privateReadonlyField不为null.

对此有任何建议 - 是否有可能?或者我需要删除"readonly"键,这不是一个好的选择.

Tim*_*ter 10

序列化能够读取只读字段的值,因为它使用反射,忽略了可访问性规则.因此,可以认为以下内容作为序列化过程的一部分是合理的,尽管我会在几乎任何其他情况下强烈反对它:

private readonly Doodad _oldField;

[OptionalField(VersionAdded = 2)]
private readonly Widget _newField;

[OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
    if (_oldField != null && _newField == null)
    {
        var field = GetType().GetField("_newField",
            System.Reflection.BindingFlags.Instance |
            System.Reflection.BindingFlags.DeclaredOnly |
            System.Reflection.BindingFlags.NonPublic);
        field.SetValue(this, new Widget(_oldField));
    }
}
Run Code Online (Sandbox Code Playgroud)


Hus*_*vic 7

声明为的任何字段private readonly都可以在声明它的同一行或构造函数中实例化.一旦完成,就无法更改.

来自MSDN:

readonly关键字是一个可以在字段上使用的修饰符.当字段声明包含只读修饰符时,声明引入的字段的赋值只能作为声明的一部分或在同一个类的构造函数中出现.

这意味着您必须删除readonly关键字才能使其生效.