反序列化时 C# 类中的字段初始值设定项不运行

2023-12-26

我有一个定义受保护字段的类。受保护的字段有一个字段初始值设定项。

当我反序列化具体类时,字段初始值设定项不会运行。为什么?解决问题的最佳模式是什么?如果我将初始化移至构造函数中,则也不会调用构造函数。

[DataContract]
public class MyConcrete
{
    // FIELD INITIALIZER DOES NOT RUN WHEN COMMENTED IN:
    protected readonly Dictionary<int, string> myDict;// = new Dictionary<int, string>();

    public MyConcrete()
    {
        myDict = new Dictionary<int, string>();
    }

    private bool MyMethod(int key)
    {
        return myDict.ContainsKey(key);
    }

    private int myProp;

    [DataMember]
    public int MyProp
    {
        get { return myProp; }
        set { bool b = MyMethod(value); myProp = value; } // Call MyMethod to provoke error
    }
}

原始类层次结构

[DataContract]
public abstract class MyAbstract
{
    // THIS INITIALIZER IS NOT RUN WHILE DESERIALIZING:
    protected readonly Dictionary<int, string> myDict = new Dictionary<int, string>();

    private bool MyMethod(int key)
    {
        return myDict.ContainsKey(key);
    }

    private int myProp;

    [DataMember]
    public int MyProp
    {
        get { return myProp; }
        set { bool b = MyMethod(value); myProp = value; } // Call MyMethod to provoke error
    }
}

[DataContract]
public class MyConcrete : MyAbstract
{

}

class Program
{
    static void Main(string[] args)
    {
        string tempfn = Path.GetTempFileName();

        MyConcrete concrete = new MyConcrete() { MyProp = 42 };
        string data = concrete.SerializeToString<MyConcrete>();

        MyConcrete rehydrated = SerializationHelper.DeserializeFromString<MyConcrete>(data);
    }
}

支持方法

static public string SerializeToString<T>(this T obj)
{
    return SerializationHelper.SerializeToString<T>(obj);
}

static public string SerializeToString<T>(T obj)
{
    DataContractSerializer s = new DataContractSerializer(typeof(T));
    using (MemoryStream ms = new MemoryStream())
    {
        s.WriteObject(ms, obj);
        ms.Position = 0;
        using (StreamReader sr = new StreamReader(ms))
        {
            string serialized = sr.ReadToEnd();
            return serialized;
        }
    }            
}

static public T DeserializeFromString<T>(string serializedDataAsString)
{
    DataContractSerializer s = new DataContractSerializer(typeof(T));
    using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(serializedDataAsString)))
    {
        object s2 = s.ReadObject(ms);
        return (T)s2;
    }
}

关于反序列化构造函数和字段初始值设定项都不会被调用 https://stackoverflow.com/a/179486/33969并使用“空白”未初始化的对象来代替。

要解决它,您可以使用OnDeserializing http://msdn.microsoft.com/en-us/library/system.runtime.serialization.ondeserializingattribute.aspx or OnDerserialized http://msdn.microsoft.com/en-us/library/system.runtime.serialization.ondeserializedattribute.aspx属性以使解串器调用具有以下签名的函数:

void OnDeserializing(System.Runtime.Serialization.StreamingContext c);

在该函数中,您可以初始化反序列化过程中遗漏的任何内容。

按照惯例,我倾向于让我的构造函数调用一个方法OnCreated()然后还有反序列化方法调用相同的东西。然后,您可以在那里处理所有字段初始化,并确保在反序列化之前触发它。

[DataContract]
public abstract class MyAbstract
{
    protected Dictionary<int, string> myDict;

    protected MyAbstract()
    {
        OnCreated();
    }

    private void OnCreated()
    {
        myDict = new Dictionary<int, string>();
    }

    [OnDeserializing]
    private void OnDeserializing(StreamingContext c)
    {
        OnCreated();
    }

    private bool MyMethod(int key)
    {
        return myDict.ContainsKey(key);
    }

    private int myProp;

    [DataMember]
    public int MyProp
    {
        get { return myProp; }
        set { bool b = MyMethod(value); myProp = value; }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

反序列化时 C# 类中的字段初始值设定项不运行 的相关文章

  • WPF DataGrid 多选

    我读过几篇关于这个主题的文章 但很多都是来自 VS 或框架的早期版本 我想做的是从 dataGrid 中选择多行并将这些行返回到绑定的可观察集合中 我尝试创建一个属性 类型 并将其添加到可观察集合中 它适用于单个记录 但代码永远不会触发多个
  • 调用 McAfee 病毒扫描引擎

    我收到客户的请求 要求使用他们服务器上的 McAfee 病毒扫描将病毒扫描集成到应用程序中 我做了一些调查 发现 McScan32 dll 是主要的扫描引擎 它导出各种看起来有用的函数 我还发现提到了 McAfee Scan Engine
  • STL 迭代器:前缀增量更快? [复制]

    这个问题在这里已经有答案了 可能的重复 C 中的预增量比后增量快 正确吗 如果是 为什么呢 https stackoverflow com questions 2020184 preincrement faster than postinc
  • C# 异步等待澄清?

    我读了here http blog stephencleary com 2012 02 async and await html that 等待检查等待的看看它是否有already完全的 如果 可等待已经完成 那么该方法将继续 运行 同步
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • 对类 static constexpr 结构的未定义引用,g++ 与 clang

    这是我的代码 a cp p struct int2 int x y struct Foo static constexpr int bar1 1 static constexpr int2 bar2 1 2 int foo1 return
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • WPF 数据绑定到复合类模式?

    我是第一次尝试 WPF 并且正在努力解决如何将控件绑定到使用其他对象的组合构建的类 例如 如果我有一个由两个单独的类组成的类 Comp 为了清楚起见 请注意省略的各种元素 class One int first int second cla
  • 如何在 Java 中测试一个类是否正确实现了 Serialized(不仅仅是 Serialized 的实例)

    我正在实现一个可序列化的类 因此它是一个与 RMI 一起使用的值对象 但我需要测试一下 有没有办法轻松做到这一点 澄清 我正在实现该类 因此在类定义中添加 Serialized 很简单 我需要手动序列化 反序列化它以查看它是否有效 我找到了
  • 使用 C# 中的 CsvHelper 将不同文化的 csv 解析为十进制

    C 中 CsvHelper 解析小数的问题 我创建了一个从 byte 而不是文件获取 csv 文件的类 并且它工作正常 public static List
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • x:将 ViewModel 方法绑定到 DataTemplate 内的事件

    我基本上问同样的问题这个人 https stackoverflow com questions 10752448 binding to viewmodels property from a template 但在较新的背景下x Bind V
  • 实例化类时重写虚拟方法

    我有一个带有一些虚函数的类 让我们假设这是其中之一 public class AClassWhatever protected virtual string DoAThingToAString string inputString retu
  • 为什么C++代码执行速度比java慢?

    我最近用 Java 编写了一个计算密集型算法 然后将其翻译为 C 令我惊讶的是 C 的执行速度要慢得多 我现在已经编写了一个更短的 Java 测试程序和一个相应的 C 程序 见下文 我的原始代码具有大量数组访问功能 测试代码也是如此 C 的
  • 为什么 std::uint32_t 与 uint32_t 不同?

    我对 C 有点陌生 我有一个编码作业 很多文件已经完成 但我注意到 VS2012 似乎有以下语句的问题 typedef std uint32 t identifier 不过 似乎将其更改为 typedef uint32 t identifi
  • MySQL Connector C/C API - 使用特殊字符进行查询

    我是一个 C 程序 我有一个接受域名参数的函数 void db domains query char name 使用 mysql query 我测试数据库中是否存在域名 如果不是这种情况 我插入新域名 char query 400 spri
  • 指针和内存范围

    我已经用 C 语言编程有一段时间了 但对 C 语言还是很陌生 有时我对 C 处理内存的方式感到困惑 考虑以下有效的 C 代码片段 const char string void where is this pointer variable l
  • Mono 应用程序在非阻塞套接字发送时冻结

    我在 debian 9 上的 mono 下运行一个服务器应用程序 大约有 1000 2000 个客户端连接 并且应用程序经常冻结 CPU 使用率达到 100 我执行 kill QUIT pid 来获取线程堆栈转储 但它总是卡在这个位置
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使

随机推荐

  • 如何获取类型的所有公共(获取和设置)字符串属性

    我正在尝试创建一个方法来遍历通用对象列表并替换它们的所有类型属性string这是null或空并更换 有什么好的方法可以做到这一点 我有这种 外壳 到目前为止 public static void ReplaceEmptyStrings
  • 停止 Django 将时间转换为 UTC

    时区让我发疯 每次我以为我已经弄清楚了 有人改变了时钟 我就会遇到十几个错误 我想我终于达到了存储正确值的地步 我的时代是timestamp with time zone在保存它们之前我不会删除时区 TIME ZONE Europe Lon
  • 我可以删除或移动文件夹 NuGetFallbackFolder 吗?

    我可以删除文件夹吗C Program Files dotnet sdk NuGetFallbackFolder 或者将其移动到其他文件夹 最好不要放在C盘 如果可以去除的话 怎么去除呢 直接删除文件夹吗 有任何副作用或损害吗 如果可以移动
  • 从未分配的内存中读取安全吗?

    从随机地址读取安全吗 我知道写作是未定义的行为 但是只阅读怎么样 嗯 在许多可视化调试器中 我可以看到任意地址的内存内容 这是怎么做到的 由于行为是不确定的 所以答案也是不确定的 或者至少是不稳定的 如果你幸运的话 随机地址是在内存范围内
  • 通过 Delphi 在网页上按下按钮 [重复]

    这个问题在这里已经有答案了 Ex1 WebBrowser OleObject Document GetElementByID ID HERE Click https stackoverflow com questions 10593494
  • 爪哇和谷歌地图

    是否可以在 Swing 或小程序中渲染谷歌地图 我知道我也可以使用美国宇航局世界风 http worldwind arc nasa gov 但对于一个简单的应用程序来说 这似乎太过分了 SwingX项目中有JXMapViewer组件 您可以
  • Web API 操作参数间歇性为空

    相关问题 Web API ApiController PUT 和 POST 方法间歇性接收空参数 https stackoverflow com questions 16091024 web api apicontroller put an
  • 如何一次处理多个 xpath(基于提要结构)或使用相同的结构创建我自己的提要

    下面的代码经过测试并且可以工作 它打印具有此结构的提要的内容
  • SwiftUI 表单对齐 macOS

    我正在尝试包含一个自定义HStackSwiftUI 中的行Form如下 var body some View Form TextField Text text constant test Toggle Toggle isOn constan
  • 将一个数组拆分为 2 个数组 C#

    编辑 我尝试过 Take Skip 方法 但出现以下错误 Cannot implicitly convert type System Collections Generic IEnumerable
  • 如何设置与爷爷的相对位置!元素?

    我有这样的布局 div class one div class two div class three some text div div div 可以根据祖父元素设置三个相对位置 one 在 CSS 中 看看这个 http jsfiddl
  • Powershell:二维数组

    以下内容按预期工作 values a b c d foreach value in values write host Value 0 value 0 write host Value 1 value 1 结果 1 Value 0 a Va
  • 用Java正则表达式递归替换?

    我可以更换ABC 10 5 with 10 5 using replaceAll ABC 1 2 但我不知道该怎么做ABC ABC 20 2 5 or ABC ABC 30 2 3 2 如果我能够转换为 20 2 5我怎样才能转换回ABC
  • 内省模块类时“#map(&proc)”习惯用法如何工作?

    介绍成语 我找到了一个有趣但无法解释的替代方案 https stackoverflow com a 3680719 1301972到一个被接受的答案 该代码显然可以在 REPL 中运行 例如 module Foo class Bar def
  • 如何在 Spring Boot 中向静态资源添加 Cache-Control 标头?

    我怎样才能添加Cache ControlSpring Boot 中静态资源的 HTTP 标头 尝试在应用程序中使用过滤器组件 它可以正确写入标头 但是Cache Control标头被覆盖 Component public class Cac
  • .NET - 使用类库存储 App.config

    网上似乎有很多人问这个问题 但到目前为止我的研究还没有得出解决方案 而且 至少目前 我还没有接受 这是不可能的 作为解决方案 简而言之 我想要做的就是在 NET 类库项目中拥有一个配置文件 该文件在任何引用该类库的应用程序中都可用 我的设置
  • 我应该为 C 中的 erand48() 使用什么种子值?

    我是 C 编程新手 我读到 erand48 是线程安全随机数生成的一个不错的选择 然而 该函数采用的种子值为 unsigned Short int array 3 关于这个种子值应该初始化为什么有什么建议吗 好吧 首先 让我澄清一下 PRN
  • 使用 PIL 加载 RGBA 位图

    我尝试使用 PIL 将 32 位位图转换为 32 位 PNG from PIL import Image im Image open example bmp print im mode it prints RGB but expected
  • 经过身份验证的播放请求的 parse.json

    我在我的应用程序中设置了身份验证 如下所示 在提供用户名且 API 密钥为 123 时始终允许 object Auth def IsAuthenticated block gt String gt Request AnyContent gt
  • 反序列化时 C# 类中的字段初始值设定项不运行

    我有一个定义受保护字段的类 受保护的字段有一个字段初始值设定项 当我反序列化具体类时 字段初始值设定项不会运行 为什么 解决问题的最佳模式是什么 如果我将初始化移至构造函数中 则也不会调用构造函数 DataContract public c