C#语法——泛型的多种应用
本篇文章主要介绍泛型的应用。
泛型是.NET Framework 2.0 版类库就已经提供的语法,主要用于提高代码的可重用性、类型安全性和效率。
泛型的定义
下面定义了一个普通类和一个泛型类,我们可以明确看到泛型类和普通类最大的区别就是多了一个<T>。
所以,这个<T>就标记了,这个类是泛型类。其中这个T,也可以写成A,B,C,D或其他字符。
public class Generic
{
public String Name;
}
public class Generic<T>
{
public T Name;
}
泛型,顾名思义,就是泛指的类型。好比男人,女人,白人,黑人,可以泛称为【人】。
但类型只能是一个类型。 那么泛型和类型之间是什么关系呢?
其实很简单,泛型在定义的时候,是泛指类型;在使用的时候,就需要被指定,到底使用哪个类型。
即,使用时,就不在是泛指类型,而是特定类型。
好比,定义时,定义了一个人。但在使用时,必须明确指定,到底是黑人还是白人。
泛型的使用
泛型类跟普通类的使用方式一样,都需要实例化对象,再由对象来调用内部的属性或方法。
下面代码实例化了泛型Generic,实例化时,还指定了该泛型Generic的指定类型为String。
所以要给泛型Generic的属性Name赋值,就需要赋值字符串类型的值。
public static void Excute()
{
Generic<String> gs = new Generic<String>();
gs.Name = "Kiba518";
}
下面代码定义了一个Int类型的泛型Generic。
public static void Excute()
{
Generic<int> gs = new Generic<int>();
gs.Name = 518;
}
泛型的默认值
泛型的默认值,如下面代码所示。需要使用default(T)来赋值。
不管泛型到底是String,int,bool或者是一个Class类型,都可以被自动赋值。
public static void Excute()
{
Generic<int> gs = new Generic<int>();
gs.Name = 518;
Generic<Task> gsTask = new Generic<Task>();
gsTask.Name = new Task(()=> {
Console.WriteLine("Kiba518");
});
} public class Generic<T>
{
public T Name = default(T);
}
泛型的约束
在泛型类中,有个特别的约束可供我们使用。
当我们不显示的声明时,这个约束不存在。但当我们显示的声明的时候,这个约束就会执行。
下面,我们来看看这个特别的约束。
public static void Excute()
{
Generic<FanXing> gFanXing = new Generic<FanXing>();
Generic<Base> gFanXingBase = new Generic<Base>();
//Generic<string> gs = new Generic<string>(); 这样定义会报错
}
public class Generic<T> where T : Base
{
public T Name = default(T);
}
public class Base
{
public string Name { get; set; }
}
public class FanXing : Base
{
public new string Name { get; set; }
}
如上面代码所示,【where T : Base】就是这个特别的约束。
当显示声明这个约束的时候,定义会限制泛型的类型。
什么是限制泛型的类型呢?
很简单,泛型T,是泛指某一个类型。我们在定义泛型类时,还需显示的指定类型,此时我们显示指定的类型,要受这个限制。
这个限制就是指【where T : Base】。
它的限制是,要求我们指定的类型T必须是Base,或者该类型继承自Base,如FanXing类。
泛型的函数
在C#中,泛型不仅可以用于类,还可以直接用于函数。
具体使用方式如下:
public static void Excute()
{
GenericFunc gf = new GenericFunc();
gf.FanXingFunc<FanXing>(new FanXing() { Name="Kiba518"});
}
public class GenericFunc
{
public void FanXingFunc<T>(T obj)
{
Console.WriteLine(obj.GetType());
}
}
很简单,调用泛型函数的时候,指定泛型函数的[指定类型]即可。
但是,这里我们发现一个问题,那就是,在泛型函数里,使用泛型对象的时候,我们发现对象都是object类型的。
那我们如果想使用泛型对象里的属性和方法时,要怎么办呢?
也很简单,反射就可以了。
下面我们添加一个反射函数GetPropertyValue,专门用来获取属性。
public class GenericFunc
{
public void FanXingFunc<T>(T obj)
{
var name = GetPropertyValue(obj, "Name");
Console.WriteLine(name);
}
public object GetPropertyValue(object obj, string name)
{
object drv1 = obj.GetType().GetProperty(name).GetValue(obj, null);
return drv1;
}
}
输出结果如下:

这样我们就得到了我们想要的结果,如果想使用泛型类里的函数,道理也一样,只需要用反射来调用即可。
结语
看到这里,有些同学可能会觉得泛型很复杂,连使用其对象下的属性,都得反射,太繁琐了,还不如不用呢。
有这样想法的同学,心里想想就好了,如果对老司机这么说,他肯定会内心默默的微笑,然后对你说,你想的没错。
然后,你就没有然后了。
泛型的应用,开篇已经说了,主要用在提高代码的可重用性、类型安全性和效率上。
如果只是定义一个类,调用一个属性,那泛型的存在就是鸡肋。
但事实上,我们的系统永远只有更复杂,更复杂,更复杂。因此泛型才有了用武之地。
----------------------------------------------------------------------------------------------------
注:此文章为原创,任何形式的转载都请联系作者获得授权并注明出处!
若您觉得这篇文章还不错,请点击下方的【推荐】,非常感谢!

C#语法——泛型的多种应用的更多相关文章
- C#面试题(转载) SQL Server 数据库基础笔记分享(下) SQL Server 数据库基础笔记分享(上) Asp.Net MVC4中的全局过滤器 C#语法——泛型的多种应用
C#面试题(转载) 原文地址:100道C#面试题(.net开发人员必备) https://blog.csdn.net/u013519551/article/details/51220841 1. . ...
- C#语法——泛型的多种应用 C#语法——await与async的正确打开方式 C#线程安全使用(五) C#语法——元组类型 好好耕耘 redis和memcached的区别
C#语法——泛型的多种应用 本篇文章主要介绍泛型的应用. 泛型是.NET Framework 2.0 版类库就已经提供的语法,主要用于提高代码的可重用性.类型安全性和效率. 泛型的定义 下面定义了 ...
- 从一知半解到揭晓Java高级语法—泛型
目录 前言 探讨 泛型解决了什么问题? 扩展 引入泛型 什么是泛型? 泛型类 泛型接口 泛型方法 类型擦除 擦除的问题 边界 通配符 上界通配符 下界通配符 通配符和向上转型 泛型约束 实践总结 泛型 ...
- C#核心语法-泛型(详细讲解泛型方法、泛型类、泛型接口、泛型约束,了解协变逆变)
泛型(generic)是C#语言2.0和通用语言运行时(CLR)的一个新特性.泛型为.NET框架引入了类型参数(type parameters)的概念.类型参数使得设计类和方法时,不必确定一个或多个具 ...
- Java学习笔记-基础语法Ⅷ-泛型、Map
泛型 泛型本质上是参数化类型,也就是说所操作的数据类型被指定为一个参数,即将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型,这种参数类型可以用在类.方法和接口中,分别为泛型类.泛型方法 ...
- C#语法——反射,架构师的入门基础。
前言 编程其实就是写代码,而写代码目的就是实现业务,所以,语法和框架也是为了实现业务而存在的.因此,不管多么高大上的目标,实质上都是业务. 所以,我认为不要把写代码上升到科学的高度.上升到艺术就可以了 ...
- C#语法——消息,MVVM的核心技术。
在C#中消息有两个指向,一个指向Message,一个指向INotify.这里主要讲INotify. INotify也有人称之为[通知],不管叫消息还是通知,都是一个意思,就是传递信息. 消息的定义 I ...
- C#语法——事件,逐渐边缘化的大哥。
事件是C#的基础之一,学好事件对于了解.NET框架大有好处. 事件最常见的比喻就是订阅,即,如果你订阅了我的博客,那么,当我发布新博客的时候,你就会得到通知. 而这个过程就是事件,或者说是事件运行的轨 ...
- C#语法——委托,架构的血液
本篇文章主要介绍委托的应用. 委托是大家最常见的语法了,但会用与精通之间的差别是巨大的. 一个程序员如果不能精通委托,那么,他永远无法成为高级程序员. 所以,让我们把委托刻到血液里吧. 这样,你才能称 ...
随机推荐
- 从构建分布式秒杀系统聊聊Disruptor高性能队列
前言 秒杀架构持续优化中,基于自身认知不足之处在所难免,也请大家指正,共同进步.文章标题来自码友 简介 LMAX Disruptor是一个高性能的线程间消息库.它源于LMAX对并发性,性能和非阻塞算法 ...
- SQL Android
SQLite是一款轻量级的关系型数据库,它的运算速度非常快,占用资源很少. 一般有以下几个关键步骤: 1.创建数据库 2.创建表 3.操作:增删改查 4.关闭数据库 5.删除表(非必选) SQLite ...
- "元素隐式具有 “any” 类型,因为类型“Shared”没有索引签名"问题解决思路
最近在构建一个typescript项目时如下代码在项目框架里vscode报错元素隐式具有 "any" 类型,因为类型“Shared”没有索引签名;很有意思的是当我们单独的把这段代码 ...
- Spring WebFlux开门迎客,却来了一位特殊客人
话说Spring WebFlux已经出现有一段时间了,但是知道他的人并不是很多.这让他很是闷闷不乐. 还有更惨的是,那些敢于吃螃蟹的人在尝试了他之后,有的竟把代码重新改回到Spring MVC的同步模 ...
- 入门系列之Scikit-learn在Python中构建机器学习分类器
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由信姜缘 发表于云+社区专栏 介绍 机器学习是计算机科学.人工智能和统计学的研究领域.机器学习的重点是训练算法以学习模式并根据数据进行预 ...
- ubuntu中使用docker部署.netcore2.1
概述 .netcore发布这么久,到现在才在项目中实际运用,之前算是了解一点,一般找工作都会问是否运用过.netcore,软件研发来说,如果这个技术没用过,觉得挺难,其实不难..netcore ...
- c# 创建Excel com加载项图片对象批量操作
技术含量较低,主要是通过VBA代码转换成c#代码而来,从而实现图片批量插入.删除.另存为的批量操作,增加文档使用的通用性. 插件主要界面如下: 主要代码如下: private void button8 ...
- c#发送邮件,可发送多个附件
1:创建SendMail类 2:调用方法 SendMail send = new SendMail("123456@qq.com", "123456@163.com&qu ...
- oppo8.0系统怎么无需Root激活Xposed框架的经验
在较多部门的引流,或业务操作中,基本都需要使用安卓的神一般的xposed框架,近期我们部门购来了一批新的oppo8.0系统,基本都都是基于7.0以上版本,基本都不能够刷入root的su权限,虽说一部分 ...
- Windows2008安装组件命令行工具ServerManagerCmd用法介绍
转自:http://blog.sina.com.cn/s/blog_537de4b5010128al.html Windows2008 安装组件服务等内容比原来复杂的多,用鼠标点来点去,既繁琐也缓慢, ...