C#泛型实例详解
本文以实例形式讲述了C#泛型的用法,有助于读者深入理解C#泛型的原理,具体分析如下:
首先需要明白什么时候使用泛型:
当针对不同的数据类型,采用相似的逻辑算法,为了避免重复,可以考虑使用泛型。
一、针对类的泛型
针对不同类型的数组,写一个针对数组的"冒泡排序"。
1.思路
● 针对类的泛型,泛型打在类旁。
● 由于在"冒泡排序"中需要对元素进行比较,所以泛型要约束成实现IComparable接口。
class Program
{
static void Main(string[] args)
{
SortHelper<int> isorter = new SortHelper<int>();
int[] iarray = {, , , , };
isorter.BubbleSort(iarray);
foreach (int item in iarray)
{
Console.Write(item+ ", ");
}
Console.ReadKey();
}
} public class SortHelper<T> where T : IComparable
{
public void BubbleSort(T[] array)
{
int length = array.Length;
for (int i = ; i <= length -; i++)
{
for (int j = length - ; j >= ; j--)
{
if (array[j].CompareTo(array[j-]) < )
{
T temp = array[j];
array[j] = array[j - ];
array[j - ] = temp;
}
}
}
}
}
运行结果如下图所示:
2.关于泛型约束
where T : IComparable 把T约束为实现IComparable接口
where T : class
where T : struct
where T : IComparable, new() 约束泛型必须有构造函数
3.关于冒泡算法
● 之所以for (int i = 0; i <= length -2; i++),这是边界思维,比如有一个长度为5的数组,如果0号位元素最终调换到4号位,每次调一个位,需要经过4次才能到4号位,即for(int i = 0; i <= 5-2, i++),i依次为0, 1, 2, 4,期间经历了4次。
● 至于for (int j = length - 1; j >= 1; j--)循环,即遍历从最后一个元素开始到索引为1的元素,每次与前一个位置上的元素比较。
4.关于比较
int类型之所以能比较,是因为int类型也实现了IComparable接口。
byte类型也一样实现了IComparable接口。
二、自定义一个类,使之也能实现冒泡算法
冒泡算法涉及到元素比较,所以自定义类必须实现IComparable接口。
class Program
{
static void Main(string[] args)
{
Book[] bookArray = new Book[];
Book book1 = new Book(, "书一");
Book book2 = new Book(, "书二");
bookArray[] = book1;
bookArray[] = book2; Console.WriteLine("冒泡之前:");
foreach (Book b in bookArray)
{
Console.WriteLine("书名:{0},价格:{1}", b.Title, b.Price);
} SortHelper<Book> sorter = new SortHelper<Book>();
sorter.BubbleSort(bookArray);
Console.WriteLine("冒泡之后:");
foreach (Book b in bookArray)
{
Console.WriteLine("书名:{0},价格:{1}", b.Title, b.Price);
}
Console.ReadKey();
}
} public class SortHelper<T> where T : IComparable
{
public void BubbleSort(T[] array)
{
int length = array.Length;
for (int i = ; i <= length -; i++)
{
for (int j = length - ; j >= ; j--)
{
if (array[j].CompareTo(array[j-]) < )
{
T temp = array[j];
array[j] = array[j - ];
array[j - ] = temp;
}
}
}
}
} //自定义类实现IComparable接口
public class Book : IComparable
{
private int price;
private string title; public Book(){} public Book(int price, string title)
{
this.price = price;
this.title = title;
} public int Price
{
get { return this.price; }
} public string Title
{
get { return this.title; }
} public int CompareTo(object obj)
{
Book book = (Book)obj;
return this.Price.CompareTo(book.Price);
}
}
运行结果如下图所示:
三、针对方法的泛型
继续上面的例子,自定义一个类,并定义泛型方法。
//方法泛型
public class MethodSortHelper
{
public void BubbleSort<T>(T[] array) where T : IComparable
{
int length = array.Length;
for (int i = ; i <= length - ; i++)
{
for (int j = length - ; j >= ; j--)
{
if (array[j].CompareTo(array[j - ]) < )
{
T temp = array[j];
array[j] = array[j - ];
array[j - ] = temp;
}
}
}
}
}
主程序如下:
class Program
{
static void Main(string[] args)
{
Book[] bookArray = new Book[];
Book book1 = new Book(, "书一");
Book book2 = new Book(, "书二");
bookArray[] = book1;
bookArray[] = book2; Console.WriteLine("冒泡之前:");
foreach (Book b in bookArray)
{
Console.WriteLine("书名:{0},价格:{1}", b.Title, b.Price);
} MethodSortHelper sorter = new MethodSortHelper();
sorter.BubbleSort<Book>(bookArray);
Console.WriteLine("冒泡之后:");
foreach (Book b in bookArray)
{
Console.WriteLine("书名:{0},价格:{1}", b.Title, b.Price);
}
Console.ReadKey();
}
}
运行结果如下图所示:
另外,使用泛型方法的时候,除了按以下:
还可以这样写:
可见,泛型方法可以根据数组实例隐式推断泛型是否满足条件。
四、泛型的其它优点
1.避免隐式装箱和拆箱
以下包含隐式装箱和拆箱:
ArrayList list = new ArrayList();
for(int i = ; i < ; i++)
{
list.Add(i); //Add接收的参数类型是引用类型object,这里包含了隐式装箱
}
for(int i = ; i < ; i++)
{
int value = (int)list[i]; //引用类型强转成值类型,拆箱
Console.WriteLine(value);
}
使用泛型避免隐式装箱和拆箱:
List<int> list = new List<int>();
for(int i = ; i < ; i++)
{
list.Add(i);
}
for(int i = ; i < ; i++)
{
int value = list[i];
Console.WriteLine(value);
}
2.能在编译期间及时发现错误
不使用泛型,在编译期不会报错的一个例子:
ArrayList list = new ArrayList();
int i = 100;
list.Add(i);
string value = (string)list[0];
使用泛型,在编译期及时发现错误:
List<int> list = new List<int>();
int i = 100;
list.Add(i);
string value = (string)list[0];
五、使用泛型的技巧
1.在当前文件中给泛型取别名
using IntList = List<int>;
IntList list = new IntList();
list.Add(1);
2.在不同文件中使用泛型别名,定义一个类派生于泛型
public class IntList : List<int>{}
C#泛型实例详解的更多相关文章
- java 泛型实例详解(普通泛型、 通配符、 泛型接口)
java 泛型详解(普通泛型. 通配符. 泛型接口) 2013-02-04 19:49:49| 分类: JAVA | 标签:java |举报|字号 订阅 下载LOFTER客户端 JDK1.5 令我们期 ...
- Java中JSON字符串与java对象的互换实例详解
这篇文章主要介绍了在java中,JSON字符串与java对象的相互转换实例详解,非常不错,具有参考借鉴价值,需要的朋友可以参考下 在开发过程中,经常需要和别的系统交换数据,数据交换的格式有XML.JS ...
- 我的书籍《深入解析Java编译器:源码剖析与实例详解》就要出版了
一个十足的技术迷,2013年毕业,做过ERP.游戏.计算广告,在大公司呆过,但终究不满足仅对技术的应用,在2018年末离开了公司,全职写了一本书<深入解析Java编译器:源码剖析与实例详解> ...
- Java中JSON字符串与java对象的互换实例详解(转)
http://www.jb51.net/article/90914.htm 在开发过程中,经常需要和别的系统交换数据,数据交换的格式有XML.JSON等,JSON作为一个轻量级的数据格式比xml效率要 ...
- linux基础-磁盘阵列(RAID)实例详解
磁盘阵列(RAID)实例详解 raid技术分类 软raid技术 硬raid技术 Raid和lvm的区别 为什么选择用raid RAID详解 RAID-0 RAID-1 RAID-5 Raid-10 R ...
- Cocos2d-x 3.X手游开发实例详解
Cocos2d-x 3.X手游开发实例详解(最新最简Cocos2d-x手机游戏开发学习方法,以热门游戏2048.卡牌为例,完整再现手游的开发过程,实例丰富,代码完备,Cocos2d-x作者之一林顺和泰 ...
- JavaScript学习笔记-实例详解-类(二)
实例详解-类(二) //===给Object.prototype添加只读\不可枚举\不可配置的属性objectId(function(){ Object.defineProperty(Object ...
- JavaScript学习笔记-实例详解-类(一)
实例详解-类(一): //每个javascript函数(除了bind())都自动拥有一个prototype对象// 在未添加属性或重写prototype对象之前,它只包含唯一一个不可枚举属性const ...
- Entity Framework实例详解
Entity Framework Code First的默认行为是使用一系列约定将POCO类映射到表.然而,有时候,不能也不想遵循这些约定,那就需要重写它们.重写默认约定有两种方式:Data Anno ...
随机推荐
- python3中使用python2中cmp函数出现错误
在python2中我们经常会使用cmp函数来比较一些东西,但是在python3中,你再来使用这个函数的时候,发现就报错了,提示找不到这个函数,这是为啥呢? 答:新版的python已经舍弃这种用法 而在 ...
- Python实现个性化推荐一
现如今,网站用推荐系统为你提供个性化的体验,告诉你买啥,吃啥甚至你应该和谁交朋友.尽管每个人口味不同,但大体都适用这个套路.人们倾向于喜欢那些与自己喜欢的其他东西相似的东西,也倾向于与自己身边的人有相 ...
- nordic mesh中的消息缓存实现
nordic mesh中的消息缓存实现 代码文件msg_cache.h.msg_cache.c. 接口定义 头文件中定义了四个接口,供mesh协议栈调用,四个接口如下所示,接口的实现代码在msg_ca ...
- JS中Document节点总结
document对象是documentHTML的一个实例,也是window对象的一个属性,因此可以将document对象作为一个全局对象来访问. Document节点的子节点可以是DocumentTy ...
- xml解析----java中4中xml解析方法(转载)
转载:https://www.cnblogs.com/longqingyang/p/5577937.html 描述 XML是一种通用的数据交换格式,它的平台无关性.语言无关性.系统无关性.给数据集成与 ...
- LintCode-56.两数之和
两数之和 给一个整数数组,找到两个数使得他们的和等于一个给定的数 target. 你需要实现的函数twoSum需要返回这两个数的下标, 并且第一个下标小于第二个下标.注意这里下标的范围是 1 到 n, ...
- python获取指定长度的字符串
from random import Random def random_str(randomlength=31): str = '' chars = 'abcdefghijklmnopqrstuvw ...
- seaj和requirejs模块化的简单案例
如今,webpack.gulp等构件工具流行,有人说seajs.requirejs等纯前端的模块化工具已经被淘汰了,我不这么认为,毕竟纯前端领域想要实现模块化就官方来讲,还是有一段路要走的.也因此纯前 ...
- anaconda安装不存在的包
Anaconda作为一个工具包集成管理工具,下载python工具包是很方便的,直接敲: conda install package_name 1 但是有时候安装一个工具包(如skimage)的时候,在 ...
- Win10修改编辑hosts文件无法保存怎么办
Win10无法修改编辑保存hosts文件怎么办?Win10系统默认是没有权限去编辑保存系统里的文件,这也是权限不够才导致修改编辑hosts后无法保存的原因,解决的办法就是把自己的帐户权限给提高就行了. ...