C#泛型序列化困境

  问题的起因是这样,有一个需求,将JsonArray转化为List,JsonArray中的元素均是string,此string可被转化为int、float、或维持string。我的方案是扩展System.Collection.Generic.List<T>,实现一个void ParseFromJsonArray(JsonArray jsArray)方法,用于将JsonArray反序列为化List<T>。按此设计思路的代码应该像下面这样。

   图一

  然后使用上应该像下面这样,可以将一个array序列化为List。

   图二

  可上述看似良好的设计却无法实现,错误原因在于Add()方法。一个List<T>的Add方法实际上是Add<T>()。所以图1中的三个Add调用实际上是像下述这样的调用。

   图三

  编译器无法将Int、Float、String转化为T。所以上述代码无法编译通过。上述就是C#泛型坑爹之处,理论上对于List<int>调用ParseFromJsonArray,这是一个确定的类型List<int>,ParseFromJsonArray将JsonArray的内容解析为int即可,可编译器在编译ParseFromJsonArray时是在编译期,编译器只认T而对具体类型(运行时类型)int一无所知,而int无法转换为T从而导致编译错误。

  所以上述设计的问题在于运行时需求与编译期行为的矛盾。如果这是C++,非常好解决,使用特化模板即可,针对int、float、string分别写一个特化函数,但是C#移除了C++中的特化模板语法,从而造成了本文的困境。

  笔者也尝试了使用约束来解决,但很遗憾,在C#中 where T : int 也是个编译器错误。从而类似C++特化模板的方法也行不通了。

最后的结论,就是在目前的C#版本中,上述由List<T>来解析出具体类型从而Add()的功能无法实现。

C#泛型序列化困境的更多相关文章

  1. .Net C# 泛型序列化和反序列化JavaScriptSerializer

    项目添加引用System.Web.Extensions /// <summary> /// 泛型序列化 /// </summary> public class JsonHelp ...

  2. C#xml泛型序列化

    using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Web ...

  3. Java ——泛型 序列化

    本节重点思维导图 泛型  序列化  泛型 import java.util.ArrayList; import java.util.Date; import java.util.Iterator; i ...

  4. c# 使用泛型序列化

    static void Serialize<T>(T instance , string fileName) { using(XmlWriter writer = new XmlWrite ...

  5. C# 序列化与反序列化之Binary与Soap无法对泛型List<T>进行序列化的解决方案

    C# 序列化与反序列化之Binary与Soap无法对泛型List<T>进行序列化的解决方案 新建Console控制台项目项目,然后添加Team和Person 这2个类,如下: Team和P ...

  6. 基于FastJson的通用泛型解决方案

    由于项目使用的是fastjson,也无法换成其他的序列化框架,所以研究了一下他对泛型序列化和反序列化的支持能力,最终解决了这个问题. 要达成的目标 我的封装方式属于通用封装,我要达到的目标是如下的使用 ...

  7. C# 序列化与反序列化Serialization之Json Xml Binary Soap JavaScript序列化

    所谓的序列化其实就是把一个内存中的对象信息转化成一个可以持久化保存的形式,方便保存数据库和文件或着用于传输, 序列化的主要作用是不同平台之间进行通信与信息的传递保存等,常用的有序列化有Json Xml ...

  8. SOFA 源码分析 — 泛化调用

    前言 通常 RPC 调用需要客户端使用服务端提供的接口,而具体的形式则是使用 jar 包,通过引用 jar 包获取接口的的具体信息,例如接口名称,方法名称,参数类型,返回值类型. 但也存在一些情况,例 ...

  9. 参考RPC

    普遍RPC在客户端需要提供接口,如果不提供则无法进行调用.同时,因为客户端也依赖提供的接口,服务端的升级.优化所带来的更新,客户端也要及时的更新API,否则会带来影响.这样,就带来了依赖接口,常常更新 ...

随机推荐

  1. Scrum立会报告+燃尽图 07

    作业要求[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2289] 版本控制:https://git.coding.net/liuyy08 ...

  2. 判断设备(PC,安Android,iOS)

    //判断是不是PC function IsPC() { var userAgentInfo = navigator.userAgent; var Agents = new Array("An ...

  3. 神之编辑器emacs

    vim被称之为编辑器之神,而emacs被成为神之编辑器. 可以当编辑器,也可以当做编译器. 编辑好后保存 输入 M-x shell 可以编译文件 g++ test.cpp -o test ./test ...

  4. 2018-2019-2 《网络对抗技术》Exp3免杀原理与实践 20165222

    1. 实践内容  1.1 正确使用msf编码器 使用 msfvenom -p windows/meterpreter/reverse_tcp -e x86/shikata_ga_nai -i 7 -b ...

  5. 转 How do GraphQL remote schemas work

    文章转自 prisma 官方博客,写的很不错 In this article, we want to understand how we can use any existing GraphQL AP ...

  6. 深入理解Java虚拟机,intern

    1,在java1.7下面,intern不再复制实例,只存第一个引用,也就是new出来的有可能和intern相同(第一次情况 2,平时的new已经暗含了一个常量池,所有不适合上面情况, 参考:https ...

  7. ZedGraph控件的使用 --归类(转帖)

    在我们编写程序的时候,有时候是要做一些统计的,为了达到一目了然的效果,饼状图,曲线图,柱状图都是很好的表现统计的直观形式.这个时候,ZedGraph控件给我们带来了极大的方便. 1.下载ZedGrap ...

  8. Linux内核 TCP/IP参数调优

    http://www.360doc.com/content/14/0606/16/3300331_384326124.shtml

  9. Python 定期检查Build_setting的编译情况

    #!/usr/bin/python #_*_ coding:utf-8 _*_ import time from email.MIMEText import MIMEText from email.M ...

  10. php去除换行符的方法小结(PHP_EOL变量的使用)

    本来在unix世界换行就用/n来代替,但是windows为了体现他的不同,就用/r/n,更有意思的是在mac中用/r.因此unix系列用 /n,windows系列用 /r/n,mac用 /r,这样就用 ...