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,否则会带来影响.这样,就带来了依赖接口,常常更新 ...
随机推荐
- Java LRU的实现
最近在leetcode上做题的时,看到了一道有关LRU Cache的题目,正好我当初面试阿里巴巴的时候问到的.主要采用linkedHashMap来实现. package edu.test.algori ...
- 为什么样本方差自由度(分母)为n-1
一.概念.条件及目的 1.概念 要理解样本方差的自由度为什么是n-1,得先理解自由度的概念: 自由度,是指附加给独立的观测值的约束或限制的个数,即一组数据中可以自由取值的个数. 2.成立条件 所谓自由 ...
- 线程的同步之Synchronized在单例模式中的应用
synchronized在单例模式中的使用 在单例模式中有一种懒汉式的单例,就是类初始化的时候不创建对象.等第一次获取的时候再创建对象.这种单例在单线程下是没有问题的获取的也都是同一个对象.但是如果放 ...
- <NET CLR via c# 第4版>笔记 第6章 类型和成员基础
6.1 类型的各种成员 6.2 类型的可见性 public 全部可见 internal 程序集内可见(如忽略,默认为internal) 可通过设定友元程序集,允许其它程序集访问该程序集中的所有inte ...
- vue: alias
resolve: { extensions: ['.js', '.vue', '.json'], alias: { '@': path.resolve('src') } }
- kmp算法中的next数组实例解释
假设求串′ababaaababaa′的next数组 模式串 a b a b a a a b a b a a 下标 1 2 3 4 5 6 7 8 9 10 11 12 1.前两位:next数组前两位一 ...
- Scrum立会报告+燃尽图 07
作业要求[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2289] 版本控制:https://git.coding.net/liuyy08 ...
- java IO 学习(二)
文件表示形式的转换: 一.从系统文件变成java中可以使用的文件对象 File file = new FIle("文件的路径"); 二.读取文件系统中文件的原始字节流,要读取字符流 ...
- C# 调用C++ DLL 的类型转换(转载版)
最近在做视频监控相关的demo开发,实现语言是C#,但视频监控的SDK是C++开发的,所以涉及到C#调用C++的dll库.很多结构体.参数在使用时都要先进行转换,由非托管类型转换成托管类型后才能使用. ...
- 常量池之字符串常量池String.intern()
运行时常量池是方法区(PermGen)的一部分. 需要提前了解: 1. JVM内存模型. 2. JAVA对象在JVM中内存分配 常量池的好处 常量池是为了避免频繁的创建和销毁对象而影响系统性能,其实现 ...