C#泛型序列化困境
【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#泛型序列化困境的更多相关文章
- .Net C# 泛型序列化和反序列化JavaScriptSerializer
项目添加引用System.Web.Extensions /// <summary> /// 泛型序列化 /// </summary> public class JsonHelp ...
- C#xml泛型序列化
using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Web ...
- Java ——泛型 序列化
本节重点思维导图 泛型 序列化 泛型 import java.util.ArrayList; import java.util.Date; import java.util.Iterator; i ...
- c# 使用泛型序列化
static void Serialize<T>(T instance , string fileName) { using(XmlWriter writer = new XmlWrite ...
- C# 序列化与反序列化之Binary与Soap无法对泛型List<T>进行序列化的解决方案
C# 序列化与反序列化之Binary与Soap无法对泛型List<T>进行序列化的解决方案 新建Console控制台项目项目,然后添加Team和Person 这2个类,如下: Team和P ...
- 基于FastJson的通用泛型解决方案
由于项目使用的是fastjson,也无法换成其他的序列化框架,所以研究了一下他对泛型序列化和反序列化的支持能力,最终解决了这个问题. 要达成的目标 我的封装方式属于通用封装,我要达到的目标是如下的使用 ...
- C# 序列化与反序列化Serialization之Json Xml Binary Soap JavaScript序列化
所谓的序列化其实就是把一个内存中的对象信息转化成一个可以持久化保存的形式,方便保存数据库和文件或着用于传输, 序列化的主要作用是不同平台之间进行通信与信息的传递保存等,常用的有序列化有Json Xml ...
- SOFA 源码分析 — 泛化调用
前言 通常 RPC 调用需要客户端使用服务端提供的接口,而具体的形式则是使用 jar 包,通过引用 jar 包获取接口的的具体信息,例如接口名称,方法名称,参数类型,返回值类型. 但也存在一些情况,例 ...
- 参考RPC
普遍RPC在客户端需要提供接口,如果不提供则无法进行调用.同时,因为客户端也依赖提供的接口,服务端的升级.优化所带来的更新,客户端也要及时的更新API,否则会带来影响.这样,就带来了依赖接口,常常更新 ...
随机推荐
- VS中的生成事件
1:为什么需要使用生成事件? 在实际开发过程中,一个公共使用的类库,在项目生成DLL后需要被复制到不同的目录下被引用,是不是觉得每次生成之后都需要人工复制是很麻烦的一件事情 我们可以利用VS中的项目生 ...
- Java例子
1. 本章学习总结 今天主要学习了三个知识点 封装 继承 多态 2. 书面作业 Q1. java HelloWorld命令中,HelloWorld这个参数是什么含义? 今天学了一个重要的命令javac ...
- Jenkins使用Git Parameter插件打包
一. 下载Git Parameter插件: 二. 项目配置: Shell脚本: #!/bin/bash -l echo $deploy_envcase $deploy_env in deploy) e ...
- python虚拟环境--virtualenv和virtualenvwrapper
python虚拟环境--virtualenv和virtualenvwrapper http://www.cnblogs.com/technologylife/p/6635631.html https: ...
- IDEA java开发学习笔记
JDK8下载地址:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 配置环境变量 ...
- PCB 设计文件中哪些可以不做成元件
PCB 文件中哪些可以不做成元件 在 PCB 设计时有些元件为了快速,实际并不需要做成元件. 因为做成元件会浪费时间,并且生产时也没有实际的元件. 如下(持续更新): PCB 与 PCB 之前的连接人 ...
- aop学习
拦截器和过滤器的区别:https://blog.csdn.net/heyeqingquan/article/details/71482169 1,aop是一个编程思想,不是具体的实现,一般有Filte ...
- stacks and queues--codility
lesson 7: stacks and queues 1. Nesting 2. StoneWall 3. Brackets 4. Finsh lesson 7: stacks and queues ...
- MAC OX 配置 Tomcat 说明
1: 首先在官网下载 Tomcat(我选择的是最新的9.0) , http://tomcat.apache.org/ 2:下载完成之后将压缩包解压在/Library/下 可使用快捷键 control+ ...
- VMware ESX常用命令 和 IP 地址修改
一. VMware ESX Command 1. 看你的esx版本 vmware –v 2. 查看显示ESX硬件,内核,存储,网络等信息 esxcfg-info -a(显示所有相关的信息) esxcf ...