《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. doris 0.9.0版本docker镜像制作与使用

    1. 安装docker 详情请参见本人博客 2. 编译doris 详情请参见doris官网文档 3. 在编译好的doris output文件夹下编写两个Dockerfile 3.1  Dockerfi ...

  2. H5的本地存储技术及其与Cookie的比较

    第一部分: H5的本地存储技术 HTML5 提供了两种在客户端存储数据的新方法.先看下面的例子: 例1:var mySelection = {name:"car", amount: ...

  3. CentOS7 YUM安装与配置 MySQL5.7

    原文链接:http://blog.csdn.net/xyang81/article/details/51759200 安装环境:CentOS7 64位,MySQL5.7 1.配置YUM源 在MySQL ...

  4. C++ #define #if #ifndef 宏指令

    不会用就直接复制粘贴 #define CURSOR(top,bottom) (((top)<<8)|(bottom)) #define mul(x1,x2) (x1*x2) #define ...

  5. 201772020113李清华《面向对象程序设计(java)》第一周学习总结

    201772020113<面向对象程序设计(java)>第一周学习总结 第一部分:课程准备部分 填写课程学习 平台注册账号, 平台名称 注册账号 博客园:www.cnblogs.com b ...

  6. leetcode1030

    class Solution(object): def __init__(self): self.List = list() def bfs(self,R,C,S,V): T = list() whi ...

  7. Mysql 和 SQLServer 使用SQL差异比较

    查询前100条数据 #mysql ; #sqlserver * from table_name ; 从数据库.表 定位表 #mysql写法:库名.表名 select password from Inf ...

  8. 创建Flask实例对象时的参数和app.run()中的参数

    app=Flask(name,static_folder=“static”,static_url_path="/aaa",template_folder=“templates”) ...

  9. <thinkphp51>如何安装cpmposer和tp51

    进入网站之后点击 进入入门指南后点击 进入安装阶段: 1.直接next 2.选择自己的PHP文件路径 3.然后下一步下一步即可. 第二部分: 下载thinkphp51 点击安装包列表 搜索:think ...

  10. tmp32dll\sha1-586.asm(1432) : error A2070:invalid instruction operands 编译openssl出错

    vs命令行工具编译openssl最新版本的时候报perl版本太低. 后来换了openssl 1.0.2的版本旧版本到是可以正常编译了,但是1.0.2应该是版本还是优点新. 编译的时候报了下面的错误: ...