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

发布于 2025-01-06 04:43:41 字数 974 浏览 0 评论 0原文

我需要在反序列化后初始化私有只读字段。我有以下 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();
    }
}

所有我需要的,反序列化后 _privateReadonlyField 不为空。

对此有什么建议吗——有可能吗? 或者我需要删除“readonly”键,这不是一个好的选择。

I need to initialize private readonly field after Deserialization. I have folowing 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();
    }
}

All what I need, that after Deserialization _privateReadonlyField is not null.

Any suggestions about this - is it possible at all?
Or I need to remove "readonly" key, which is not a good option.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

柠檬色的秋千 2025-01-13 04:43:41

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

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));
    }
}

Serialization is able to read in values for read-only fields because it uses reflection, which ignores accessibility rules. It can be argued that the following is, therefore, justified as part of the serialization process, even though I would recommend strongly against it in almost any other circumstance:

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));
    }
}
掩于岁月 2025-01-13 04:43:41

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

来自 MSDN

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

这意味着您必须删除 readonly 关键字才能使其正常工作。

Any field declared as private readonly can be instantiated in the same line where it was declared or inside a constructor. Once that is done it cannot be changed.

From MSDN:

The readonly keyword is a modifier that you can use on fields. When a field declaration includes a readonly modifier, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class.

That means that you will have to remove readonly keyword to get it to work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文