C++的泛型是基于模板(template)技术的。模板本身并不作为独立的编译单元,而是在编译时绑定实际参数类型进行模板实例化,类似与C语言的宏展开,在运行时并不存在独立的模板类型。模板对泛型参数的约束是基于操作的语法特征的,属于一种静态的duck typing机制,十分灵活。

下面的代码定义了一个泛型Add函数,它对泛型参数T的要求只是支持+运算,并不要求T是某个类的子类,或是实现了某个接口。int, double, std::string等支持+运算符的类型都可以成功匹配T。

//C++

template<typename T>
T Add(const T& t1, const T& t2) {
    return t1 + t2;
}

int main() {
    int i = Add(1, 2);
    double d = Add(1.1, 2.2);
    std::string s = Add(std::string("abc"), std::string("def"));

std::cout << i << " " << d << " " << s << std::endl;

return 0;
}

输出:

>>3 3.3 abcdef

而类似的代码在C#中却无法编译通过:

这是由于C#采用基于reification的泛型机制,泛型类会单独编译,并且在运行时存在;因此,C#对于泛型参数的要求更加严格,只能通过where关键字表达基于继承关系的约束,无法通过duck typing的方式表达类型约束。与模板相比,这种机制的好处在于可以更好的支持反射和元编程,但其缺点是泛型的表达能力不如模板。幸好C#4.0中引入了动态类型机制,我们可以通过动态类型来实现基于duck typing的泛型参数约束。

//C#

static class Calculator {
    public static T Add<T>(T t1, T t2) {
        dynamic d1 = t1;
        dynamic d2 = t2;

return (T)(d1 + d2);
    }
}

public static void Main(string[] args){
    int i = Calculator.Add(1, 2);
    double d = Calculator.Add(1.1, 2.2);
    string s = Calculator.Add("abc", "def");

Console.WriteLine(i + " " + d + " " + s);

}

输出:

>>3 3.3 abcdef

除了运算符重载,对于普通的方法调用也是适用的。这种方法是一种动态duck typing的泛型参数约束机制,依赖于运行时的方法查找,与模板编译时的检查不同,它需要使用者保证传入的对象符合相应要求。

用dynamic增强C#泛型表达力相关推荐

  1. A.CTable开源框架Mybatis增强自动创建表/更新表结构/实现类似hibernate共通的增删改查-mybatis-enhance-actable

    mybatis-enhance-actable-1.3.1.RELEASE 项目已更新既支持传统Spring项目也支持Springboot项目,同时支持tk.mybatis能够支持更强大的CUDR(为 ...

  2. Swift 4.1增强了泛型、编译器和包管理器

    \ 看新闻很累?看技术新闻更累?试试下载InfoQ手机客户端,每天上下班路上听新闻,有趣还有料! \ \\ Swift 4.1发布正式版,它为Swift包管理器和Foundation带来了新的语言特性 ...

  3. 进阶04 4 Collection集合类+Iterator迭代器+增强for+泛型

    文章目录 Collection集合 集合概述 java.util.Collection接口 Iterator迭代器 Iterator接口 Iterator接口的常用方法 说明 迭代器实现原理图: 增强 ...

  4. Wpf DataGrid 绑定Dynamic (二维数据表)

    最近有一个需求,需要根据用户数据动态生成二维数据表,绑定到表格后,用户再次编辑数据,最后再将编辑过的数据,生成类型数据,存入数据库. 仔细分析过后,觉得最适合的方式,莫过于给DataGrid绑定Dyn ...

  5. c# dynamic 无法创建 泛型变量的问题

    IMyClass<T> FunctionA<T>( object arg_obj) { dynamic dyObj = arg_obj; return new MyClass& ...

  6. oracle10g执行insert,oracle 10g 增强审计。表insert 及bind values

    oracle 10g之前,可以审计对表的操作,但不能记录操作时的各个列的值.在10g中,已经可以审核并监控到具体的sql语句及内容了. 要求 10g以后的版本. alter system set au ...

  7. ​ICLR 2023 | 表达力 v.s. 泛化性:我们真的需要更强大的GNN吗?

    本文分享一篇 ICLR 2023 的最新工作,通过大量实验和理论分析揭示了图学习领域的一个普遍现象,对 GNN 的本质性原理引发了一系列新的思考. 论文题目:  Graph Neural Networ ...

  8. C# 高级编程个人笔记搬运 一(基础知识)

    今天天气不错,连夜下了场大雨后一切湿漉漉的.是的,我又回来接着写了,我又要看新的书了,怕自己忘记了之前看过的,大概搬运下旧书笔记.一边给新书记笔记,一遍搬运旧的,说不定可以打通任督二脉. 扎个马步: ...

  9. 系统学习Go语言,有这几本书就够了!

    最新个人博客 shankusu.me 以下内容转载自 https://tonybai.com/2020/11/04/the-recommend-books-list-for-learning-go/ ...

最新文章

  1. #每天一种设计模式# 观察者模式
  2. arch更新失败的办法
  3. android高德地图显示多点标记,高德地图多点标记自定义地图
  4. Linux0.11小结
  5. 有kotlin中的Android项目编译出现 Unresolved reference: R
  6. Kruskal重构树
  7. Django 第十二课 【class meta】
  8. Linux系统特殊符号的作用
  9. cmk聪明客机器人餐厅_住了10年的老房大改造,45客餐厅全开放,更有整面大衣柜,高级又实用!...
  10. 解决Emacs输出PDF文件时Tex缺少.sty文件的方法
  11. 从面试题中看Java的Reference(引用)
  12. dreamweaver序列号免费_dreamweaver8【dreamweaver8序列号】dreamweaver8注册码序列号简体中文版...
  13. 成为阿里云架构师的进阶之路——阿里云首批ACE认证通过者逸疏专访
  14. xp计算机护眼模式,xp系统桌面上老是显示护眼模式!(图)
  15. LK_Novel_DL 轻国小说下载工具 Docx Python
  16. 聚类——K均值简介及Python实现
  17. 数据可视化工具-Vue-DataV入门
  18. esxi下搭建软路由
  19. Marshmallow 库
  20. 梯度提升回归树(GBDT)

热门文章

  1. 信息学奥赛一本通 1258:【例9.2】数字金字塔
  2. 信息学奥赛一本通(1128:图像模糊处理)
  3. 理论基础 —— 索引 —— B 树、B+ 树与 B* 树
  4. Passing the Message(HDU-3410)
  5. Linux 使用正则表达式的常用命令
  6. 信息学奥赛C++语言:移数问题
  7. 信息学奥赛一本通C++语言——1029:计算浮点数相除的余
  8. 61 SD配置-科目分配-分配税收确定的交货工厂
  9. C++:new[]和delete[]一定要配对使用吗?
  10. Window下更新python pip源