1、泛型

泛型是framwork2.0推出的新语法,具有延迟声明的特点:把参数类型的声明推迟到调用的时候。泛型不是一个语法糖,是框架升级提供的功能。需要编辑器和JIT(just-in-time compilation、即时编译)的支持。

泛型并不存在性能问题,因为编译器支持 ,在即时编译的时候,编译器会生成一个泛型方法的副本,基本上和固定类型的方法性能无差别。

泛型的用处就是 用一个类、方法、接口、委托来满足不同的具体类型,然后做一样的事情。

泛型的约束有以下几种类型:

  1. 基类约束
  2. 接口约束
  3. 引用类型约束
  4. 值类型约束
  5. 无参数构造函数约束

约束必须是接口、非密封类(密封类无法被继承,不存在子类,所以约束没有意义)、类型参数;

约束可叠加,

泛型约束主要是用来保证代码安全。

2、协变逆变

这里用代码来解释一下这两个概念

 using System;
using System.Collections.Generic; namespace Util_YCH.Build.泛型
{
/// <summary>
/// 协变实例
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IListAnimals<out T> {
/// <summary>
/// T只能作为返回值不能作为入参
/// </summary>
/// <returns></returns>
T GetT();
/// <summary>
/// 所以这里会编译报错
/// </summary>
/// <param name="t"></param>
void setT(T t);
}
public class ListAnimals<T> : IListAnimals<T>
{
T t;
public T GetT()
{
throw new NotImplementedException();
} public void setT(T t)
{ }
}
/// <summary>
/// 逆变实例
/// </summary>
/// <typeparam name="T"></typeparam>
public interface IListDogs<in T>
{
/// <summary>
/// T只能作为入参不能作为返回值
/// </summary>
/// <param name="t"></param>
void setT(T t);
/// <summary>
/// T无法作为返回值,此处会编译报错
/// </summary>
/// <returns></returns>
T GetT(); }
public class ListDogs<T> : IListDogs<T>
{
public T GetT()
{
throw new NotImplementedException();
} public void setT(T t)
{
throw new NotImplementedException();
}
}
/// <summary>
/// 动物类
/// </summary>
public class Animal
{
}
/// <summary>
/// 狗类
/// </summary>
public class Dog : Animal
{
} public class Test {
public Test(){ Animal animal1 = new Animal();
Dog dog = new Dog();
Animal animal2 = new Dog();//狗是动物
List<Animal> animals = new List<Dog>();
//按照常规而言,Dog是Animal的子类,这样写应该是没有问题的,凡是编译器报错,
//原因是因为Dog是Animal的子类,但是List<Dog> 与 List<Animal> 之间不存在继承关系,
//于是为了消除这个BUG,就有了【协变】的概念
#region 协变
IListAnimals<Animal> listAnimals = new ListAnimals<Dog>();
#endregion
#region 逆变
IListDogs<Dog> listAnimals2 = new ListDogs<Animal>();
#endregion
} }
}

3、泛型缓存

由于CLR会针对不同的类型会生成一个副本,所以可以实现泛型的缓存,示例代码如下

 using System;

 namespace Util_YCH.Build.泛型
{
/// <summary>
/// 每个不同的类型T都会生成一个副本,
/// 根据C#语言特性,静态字段和方法会在程序第一次运行的时候执行,缓存效率远远高于字典等缓存。
/// </summary>
public class Cache<T>
{
public Cache()
{
CacheStr = DateTime.Now.ToString();
}
private static string CacheStr = "";
public static string GetCacheStr() {
return CacheStr;
}
} public class Test {
public Test(){ #region 泛型缓存
var cache1 = new Cache<int>();
var cache2 = new Cache<string>();
var cache3 = new Cache<DateTime>();
var cache4 = new Cache<double>();
var cache5 = new Cache<bool>();
#endregion var cache11 = Cache<int>.GetCacheStr();
var cache12 = Cache<int>.GetCacheStr();
Console.WriteLine(cache11 == cache12);
Console.ReadKey();
} }
}

字典缓存是哈希结构的,读取缓存的时候需要进行查找,会消耗一定的资源;而泛型缓存的副本存在于内存里面,查找起来速度极快,但是有局限性,就是和类型相关,具有一定的限制。

这里的应用场景我能想到的就是可以针对每个实体缓存CRUD的Sql语句。

C#进阶之泛型(Generic)的更多相关文章

  1. Java - 泛型 ( Generic )

    Java - 泛型 ( Generic )     > 泛型的特点         > 解决元素存储的安全性问题         > 解决获取数据元素时,需要类型强转的问题     ...

  2. Java之集合初探(二)Iterator(迭代器),collections,打包/解包(装箱拆箱),泛型(Generic),comparable接口

    Iterator(迭代器) 所有实现了Collection接口的容器都有一个iterator方法, 用来返回一个实现了Iterator接口的对象 Iterator对象称作迭代器, 用来方便的实现对容器 ...

  3. 谈一谈从 Delphi 2009 之后就支援的重要功能 – 泛型 (Generic)

    前言 在C++的语言基础当中,除了物件导向.事件驱动的概念之外,模版设计(Template)也是非常重要的一环.然而,C++的开发人员能够善用模版设计的并不多.模版设计这个好物,一般还有一个名称,就是 ...

  4. JAVA中的泛型(Generic)

    Java泛型(Generic)简介 泛型是jdk1.5版本以后推出来的,表示类型参数化,让java能更具有动态性一些,让类型能变成参数传递. 要我自己感觉的话,泛型本身没啥用,跟反射在一起用,就体现出 ...

  5. Dephi泛型generic的应用

    Dephi泛型generic的应用   泛型在C++, C#中已有广泛应用,Delphi自2009版本也引入泛型,典型的应用如TList,TDictionary.如果你熟悉C#,其用法十分类似. 比如 ...

  6. Java基础之Comparable接口, Collections类,Iterator接口,泛型(Generic)

    一.Comparable接口, Collections类 List的常用算法: sort(List); 排序,如果需要对自定义的类进行排序, 那就必须要让其实现Comparable接口, 实现比较两个 ...

  7. Java自学-集合框架 泛型Generic

    ArrayList上使用泛型 步骤 1 : 泛型 Generic 不指定泛型的容器,可以存放任何类型的元素 指定了泛型的容器,只能存放指定类型的元素以及其子类 package property; pu ...

  8. C#泛型(Generic)

    一.什么是泛型 泛型(Generic)是C#语言2.0.通用语言运行时(CLR)2.0..NET Framework2.0推出来的新特性. 泛型为.NET框架引入类型参数(Type Parameter ...

  9. .NET知识梳理——1.泛型Generic

    1. 泛型Generic 1.1        引入泛型:延迟声明 泛型方法声明时,并未写死类型,在调用的时候再指定类型. 延迟声明:推迟一切可以推迟的. 1.2        如何声明和使用泛型 泛 ...

  10. C# 泛型Generic

    泛型(Generic),是将不确定的类型预先定义下来的一种C#高级语法,我们在使用一个类,接口或者方法前,不知道用户将来传什么类型,或者我们写的类,接口或方法相同的代码可以服务不同的类型,就可以定义为 ...

随机推荐

  1. VMware配置NAT方式下的静态ip

    一.VMware上NAT模式工作原理 原理图如下: 说明: 1.虚拟主机与本地主机通信时,直接通过虚拟交换机访问(不管是虚拟主机的ip是静态ip还是动态分配的ip) 2.虚拟主机与外网通信时,虚拟主机 ...

  2. 记录学习Linux过程

    第一步fdisk-l 出错 Permission denied? ubuntu@VM-0-6-ubuntu:~$ fdisk -l fdisk: cannot open /dev/vda: Permi ...

  3. Mac系统下,docker安装nextcloud,打造个人本地网盘

    1.安装docker 推荐下载地址:http://get.daocloud.io/#install-docker-for-mac-windows   2.拉取镜像 $ docker pull next ...

  4. springBoot2.X---过滤器,监听器,拦截器

    过滤器,监听器,拦截器 一.画图理解 过滤器(filter),监听器(listener),拦截器(Interceptor). 通过两幅图我们可以理解拦截器和过滤器的特点 1.过滤器 过滤器是在请求进入 ...

  5. UML 2.5版本与UML分类概述

    UML 2.5版本与UML分类概述 转 http://www.umlstudy.com/uml-25-diagrams.html UML简述 UML图是设计.实现或已经存在的系统模型的部分图形表示(视 ...

  6. selenium 等待时间

    三种时间模式:1.隐性等待:①等待页面所有元素都加载完才执行下一步,如果在设定的时间内没有加载完成所有元素,则抛出异常②隐式等待对整个driver周期都起作用,即设置一次后,所有执行都会有效from ...

  7. 数据中心网络架构的问题与演进 — 混合云与 VPC 专有网络

    目录 文章目录 目录 前文列表 历史背景 混合云 Why hybrid cloud? 混合云市场 混合云的逻辑架构 混合云应用场景 灾难恢复 数据备份 负载扩容 应用部署 开发测试生产部署 混合云产品 ...

  8. 关于Server2008 R2日志的查看

    Server 2008 r2通过 系统事件查看器 分析日志: 查看 系统 事件: 事件ID号: 审计目录服务访问 4934 - Active Directory 对象的属性被复制 4935 -复制失败 ...

  9. 小D课堂-SpringBoot 2.x微信支付在线教育网站项目实战_5-10.Springboot2.x用户登录拦截器开发实战

    笔记 10.Springboot2.x用户登录拦截器开发实战     简介:实战开发用户登录拦截器拦截器 LoginInterceptor                  1.实现接口 LoginI ...

  10. Swift的if let和guard let的使用 <一看就懂哟>

    // // ViewController.swift // 可选项的判断 // // Created by 思 彭 on 16/9/16. // Copyright © 2016年 思 彭. All ...