《C#从现象到本质》读书笔记(七)第9章 泛型

泛型的三大好处:类型安全,增强性能(避免装箱和拆箱),代码复用。

泛型方法是传入的参数至少有一个类型为T(尚未制定的类型,根据微软的命名规则,通常以T开头)的方法。T称为类型参数。

它的使用契机一般为:传入类型可能有很多种、但处理方式却相同的情景。这是可以不需要写很多歌重载,而考虑用泛型方法达到代码复用的目的。

同名的泛型方法和非泛型方法会被编译器看做不同的方法。即使都是泛型方法,不同个数的类型参数也会被编译为不同的方法。

泛型约束使得类型参数只能是满足某些条件的类型。它分为如下几类:

1)接口约束。2)基类型约束。基类型约束必须放在其他约束之前。3)构造函数new()约束。new()约束出现在where子句的最后。

多个泛型类型参数,如where T:class where U:struct。

 class Program
{
static void Main(string[] args)
{
var r1 = new Rectangle(, );
var r2 = new Rectangle(, );
Compare(r1, r2, CompareRectangle); var c1 = new Cirtle();
var c2 = new Cirtle();
Compare(c1, c2, CompareCircle); Console.ReadKey();
}
public static int CompareRectangle(Rectangle r1, Rectangle r2)
{
double r1Area = r1.Length * r1.Width;
double r2Area = r2.Length * r2.Width;
if (r1Area > r2Area) return ;
if (r1Area < r2Area) return -;
return ;
}
public static int CompareCircle(Cirtle c1, Cirtle c2)
{
if (c1.Radius > c2.Radius) return ;
if (c1.Radius < c2.Radius) return -;
return ;
}
public static void Compare<T>(T o1, T o2, Func<T, T, int> rule)
{
var ret = rule.Invoke(o1, o2);
if (ret == ) Console.WriteLine("第一个大");
if (ret == -) Console.WriteLine("第二个大");
if (ret == ) Console.WriteLine("一样大");
}
}
public struct Rectangle
{
public double Length { get; set; }
public double Width { get; set; } public Rectangle(double l, double w)
: this()
{
Length = l;
Width = w;
}
}
public struct Cirtle
{
public double Radius { get; set; } public Cirtle(double r)
: this()
{
Radius = r;
}
}

可变性是以一种类型安全的方式,将一个对象作为另一个对象来使用。可变性有两种类型:

1)协变。子类隐式转换为父类,若某方法声明返回类型为object,那么实际上它可以返回任何的类型。

2)逆变。父类隐式转换为子类。

“协变”->”和谐的变”->”很自然的变化”->string->object :协变。

“逆变”->”逆常的变”->”不正常的变化”->object->string 逆变。

协变性和out关键字搭配使用,用于向调用者返回操作的值。接口中的T职能出现在输出中(包括方法的输出、属性的get访问器和委托的参数,因为委托支持协变),不能出现在输入中。

逆变性和in关键字搭配使用,此时类型出现在输入(包括方法的输入、属性的set访问器和委托的参数,因为委托支持逆变)。

协变和逆变体现在泛型类T和T的派生类。out和in关键字只能在接口和委托中使用,不支持泛型方法和泛型类。而且,值类型不参与协变和逆变。

C#中泛型可变性的限制:

1)只有接口和委托可以拥有可变的类型参数。in和out关键字只能用来修饰泛型接口和泛型委托。

2)可变性只能用于引用类型,禁止任何值类型之间的转换,以及值类型和引用类型之间的转换。

3)类型参数使用了out或者ref将禁止可变性。

4)不允许部分可变性。5)多播委托于可变性不能混用。

如果一个接口需要对T协变,那么这个接口所有方法的输入参数类型必须支持对T的逆变。如果接口要支持对T逆变,那么接口中方法的参数类型都必须支持对T协变。

《C#从现象到本质》读书笔记(七)第9章 泛型的更多相关文章

  1. C++ Primer 读书笔记:第11章 泛型算法

    第11章 泛型算法 1.概述 泛型算法依赖于迭代器,而不是依赖容器,需要指定作用的区间,即[开始,结束),表示的区间,如上所示 此外还需要元素是可比的,如果元素本身是不可比的,那么可以自己定义比较函数 ...

  2. SQL Server2012 T-SQL基础教程--读书笔记(8 - 10章)

    SQL Server2012 T-SQL基础教程--读书笔记(8 - 10章) 示例数据库:点我 CHAPTER 08 数据修改 8.1 插入数据 8.1.1 INSERT VALUES 语句 8.1 ...

  3. 《Android开发艺术探索》读书笔记 (13) 第13章 综合技术、第14章 JNI和NDK编程、第15章 Android性能优化

    第13章 综合技术 13.1 使用CrashHandler来获取应用的Crash信息 (1)应用发生Crash在所难免,但是如何采集crash信息以供后续开发处理这类问题呢?利用Thread类的set ...

  4. 《Android开发艺术探索》读书笔记 (3) 第3章 View的事件体系

    本节和<Android群英传>中的第五章Scroll分析有关系,建议先阅读该章的总结 第3章 View的事件体系 3.1 View基本知识 (1)view的层次结构:ViewGroup也是 ...

  5. 《Linux内核设计与实现》读书笔记——第一、 二章

    <Linux内核设计与实现>读书笔记--第一. 二章 标签(空格分隔): 20135321余佳源 第一章 Linux内核简介 1.Unix内核特点 十分简洁:仅提供几百个系统调用并且有明确 ...

  6. MDX Step by Step 读书笔记(七) - Performing Aggregation 聚合函数之 Max, Min, Count , DistinctCount 以及其它 TopCount, Generate

    MDX 中最大值和最小值 MDX 中最大值和最小值函数的语法和之前看到的 Sum 以及 Aggregate 等聚合函数基本上是一样的: Max( {Set} [, Expression]) Min( ...

  7. 《Android开发艺术探索》读书笔记 (9) 第9章 四大组件的工作过程

    第9章 四大组件的工作过程 9.1 四大组件的运行状态 (1)四大组件中只有BroadcastReceiver既可以在AndroidManifest文件中注册,也可以在代码中注册,其他三个组件都必须在 ...

  8. 【记】《.net之美》之读书笔记(二) C#中的泛型

    前言 上一篇读书笔记,很多小伙伴说这本书很不错,所以趁着国庆假期,继续我的读书之旅,来跟随书中作者一起温习并掌握第二章的内容吧. 一.理解泛型 1.为什么要使用泛型?-----通过使用泛型,可以极大地 ...

  9. Android群英传》读书笔记 (3) 第六章 Android绘图机制与处理技巧 + 第七章 Android动画机制与使用技巧

    第六章 Android绘图机制与处理技巧 1.屏幕尺寸信息屏幕大小:屏幕对角线长度,单位“寸”:分辨率:手机屏幕像素点个数,例如720x1280分辨率:PPI(Pixels Per Inch):即DP ...

  10. 【锋利的Jquery】读书笔记七

    第七章  jquery插件 管理cookie的插件--cookie jquery插件太多没什么好讲的,百度太多 说以下 cookie插件 <!DOCTYPE html> <html& ...

随机推荐

  1. html/css/js-横向滚动条的实现

    在前端UI设计时,网页的制作很麻烦,深有感悟!碰到太多的不懂,或是第一次见,就要去网上找资料!横向滚动条就是我遇到麻烦中其中的一个,其实也 很简单,只是在几次项目中都用到了这个横向滚动条所以就拿出来说 ...

  2. 转:细说ASP.NET Windows身份认证

    转自:https://www.cnblogs.com/fish-li/archive/2012/05/07/2486840.html 细说ASP.NET Windows身份认证 阅读目录 开始 认识A ...

  3. Vue中table合并单元格用法

    <table> <tr> <th>地名</th> <th>结果</th> <th>人名</th> < ...

  4. Permanent Space 和 Heap Space

      JVM堆内存 JVM堆内存分为2块:Permanent Space 和 Heap Space. Permanent 即 持久代(Permanent Generation),主要存放的是Java类定 ...

  5. nginx 返回数据不完整

    当nginx 代理解析大量数据流时,会把数据先放在自己的缓冲区,然后一并发给客户端 一次请求的数据量很大, 则会有一部分数据会被忽略掉 前端解析数据会有问题 致使页面白屏 nginx 返回数据不完整的 ...

  6. 学习笔记:AngularJs

    站点: http://www.angularjs.cn/  angularjs中文社区 http://www.jb51.net/article/60733.htm  AngularJS内置指令 基本页 ...

  7. Ubuntu 14.03 安装jdk

    安装python-software-properties $sudo apt-get install python-software-properties $sudo apt-get install ...

  8. EasyARM-iMX283A的U盘使用教程

    在编写代码前我们先来EasyARM-iMX283A对U盘使用的操作. 我们先拿一个U盘进行格式化 在U盘中写一些文件保存后,弹出U盘. 将U盘插入EasyARM-iMX283A的开发板. [注意]Ea ...

  9. chrome视频播放加速

    安装video speed controller, 下载源码https://github.com/igrigorik/videospeed,解压 在chrome输入chrome://extention ...

  10. docker mysql Exit 1

    用laradock启动mysql时,state总是 Exit 1 ,docker-compose build后也没有效果 这时应该在-/.laradock/data(.env的DATA_PATH_HO ...