《C#高级编程》之泛型--1创建泛型类
.NET自从2.0版本开始就支持泛型。
- 非泛型链表
闲话休提,马上来看下非泛型的简化链表类,它可以包含任意类型的对象。
LinkedListNode.cs中:
在链表中,一个元素引用另一个元素,所以必须创建一个类,将其封装在链表中,并引用下一个对象。
public class LinkedListNode
{
public LinkedListNode(object value)
{
this.Value = value;
} public object Value { get; private set; } public LinkedListNode Next { get; internal set; }
public LinkedListNode Prev { get; internal set; }
}
LinkedListNode.cs中:
LinkedList类包含LinkedListNode类型的First,与Last属性,它们分别标志了链表的头尾。通过实现GetEnumerator()方法,可以用foreach语句遍历链表。
public class LinkedList : IEnumerable
{
public LinkedListNode First { get; private set; }
public LinkedListNode Last { get; private set; } public LinkedListNode AddLast(object node)
{
var newNode = new LinkedListNode(node);
if (First == null)
{
First = newNode;
Last = First;
}
else
{
Last.Next = newNode;
Last = newNode;
}
return newNode;
} public IEnumerator GetEnumerator()
{
LinkedListNode current = First;
while (current != null)
{
yield return current.Value;
current = current.Next;
}
}
Program.cs中:
var list1 = new LinkedList();
list1.AddLast();
list1.AddLast();
list1.AddLast(""); foreach (int i in list1)
{
Console.WriteLine(i);
}
此时,会出现一个运行异常,因为把链表中第3个元素转换成整形时会出现异常。

- 泛型链表
为了避免这种情况,下面创建泛型的链表。
LinkedListNode.cs中:
LinkedListNode类用一个泛型类型T声明。属性Value的类型是The,而不是object.
public class LinkedListNode<T>
{
public LinkedListNode(T value)
{
this.Value = value;
} public T Value { get; private set; }
public LinkedListNode<T> Next { get; internal set; }
public LinkedListNode<T> Prev { get; internal set; }
}
LinkedList.cs中:
也把LinkedList定义成泛型类。
1 public class LinkedList<T> : IEnumerable<T>
{
public LinkedListNode<T> First { get; private set; }
public LinkedListNode<T> Last { get; private set; } public LinkedListNode<T> AddLast(T node)
{
var newNode = new LinkedListNode<T>(node);
if (First == null)
{
First = newNode;
Last = First;
}
else
{
Last.Next = newNode;
Last = newNode;
}
return newNode;
} public IEnumerator<T> GetEnumerator()
{
LinkedListNode<T> current = First; while (current != null)
{
yield return current.Value;
current = current.Next;
}
} IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Program.cs中:
class Program
{
static void Main()
{
var list2 = new LinkedList<int>();
list2.AddLast();
list2.AddLast();
list2.AddLast(); foreach (int i in list2)
{
Console.WriteLine(i);
} var list3 = new LinkedList<string>();
list3.AddLast("");
list3.AddLast("four");
list3.AddLast(null); foreach (string s in list3)
{
Console.WriteLine(s);
}
Console.Read(); }
现在foreach是类型安全的了。

《C#高级编程》之泛型--1创建泛型类的更多相关文章
- C#高级编程:泛型优点和特性
泛型是CLR 2.0的一个新特性,在CLR 1.0中,要创建一个灵活的类或方法,但该类或方法在编译期间不知道使用什么类,就得以Object类为基础.而Object在编译期间没有类型安全性,因此必须进行 ...
- 解读经典《C#高级编程》泛型 页114-122.章4
前言 本章节开始讲解泛型..Net从2.0开始支持泛型,泛型不仅是C#的一部分,也与IL代码紧密集成.所以C#中泛型的实现非常优雅.相对于C#,Java是后期引入的泛型,受限于最初的设计架构,就实现的 ...
- 解读经典《C#高级编程》泛型 页122-127.章4
前言 本篇继续讲解泛型.上一篇讲解了泛型类的创建.本篇讲解泛型类创建和使用的细节. 泛型类 上篇举了个我产品中用到的例子,本篇的功能可以对照着此案例进行理解. /// <summary> ...
- C#高级编程之泛型一(泛型的引入、泛型的使用、何为泛型)
为何引入泛型 当我们要对不同类型的参数执行类似的方法时:如下所示功能打印传入参数的相关信息. class CommonMethdod { /// <summary> /// show in ...
- C#高级编程之泛型二(泛型类型约束、类型、反射与泛型)
泛型类型约束 简言之:对泛型类型进行约束,细化,限定. MSDN的定义:泛型定义中的 where 子句指定对用作泛型类型.方法.委托或本地函数中类型参数的参数类型的约束,意思就是可以有泛型类.泛型方法 ...
- C#高级编程之泛型三(协变与逆变)
为何引入协变.逆变 我们知道一个子类对象可以赋值给一个基类对象 Animal animal = new Animal(); Animal cat = new Cat(); 那如果是用在泛型里面能行嘛? ...
- C#高级编程笔记 Day 7, 2016年9月 19日 (泛型)
1.协变和抗变 泛型接口的协变 如果泛型类型用 out 关键字标注,泛型接口就是协变的.这也意味着返回类型只能是 T. 接口IIndex 与类型T 是协变的,并从一个制度索引器中返回这个类型. pu ...
- 【读书笔记】C#高级编程 第五章 泛型
(一)泛型概述 泛型不仅是C#编程语言的一部分,而且与程序集中的IL代码紧密地集成.泛型不仅是C#语言的一种结构,而且是CLR定义的.有了泛型就可以创建独立于被包含类型的类和方法了. 1.性能 泛型的 ...
- 重学《C#高级编程》(泛型与数组)
前段时间工作比较忙,就没有写随笔了,现在继续. 前两天重新看了泛型和数组两章,简单说下我自己的收获吧 泛型 我们知道数组是一种批量的数据格式,而泛型其实就是一种自定义的批量数据格式,当数组和C#现有的 ...
随机推荐
- hdu 2639 Bone Collector II (01背包,求第k优解)
这题和典型的01背包求最优解不同,是要求第k优解,所以,最直观的想法就是在01背包的基础上再增加一维表示第k大时的价值.具体思路见下面的参考链接,说的很详细 参考连接:http://laiba2004 ...
- 全注解的SSH框架
基于struts2.23 + spring2.5.6 + hibernate3.6.4 + hibernate-generic-dao1.0(除了spring,我整合的都是最新的GA包,hiberna ...
- POJ 1144 Network(Tarjan)
题目链接 题意 : 找出割点个数. 思路 : Tarjan缩点,u是割点的充要条件是:u要么是具有两个以上子女的深度优先生成树的根,要么不是根,而有一个子女v满足low[v]>=dfn[u]. ...
- 2014多校第二场1011 || HDU 4882 ZCC Loves Codefires (贪心)
题目链接 题意 : 给出n个问题,每个问题有两个参数,一个ei(所要耗费的时间),一个ki(能得到的score).每道问题需要耗费:(当前耗费的时间)*ki,问怎样组合问题的处理顺序可以使得耗费达到最 ...
- MySQL5.6 Replication主从复制(读写分离) 配置完整版
MySQL5.6 Replication主从复制(读写分离) 配置完整版 MySQL5.6主从复制(读写分离)教程 1.MySQL5.6开始主从复制有两种方式: 基于日志(binlog): 基于GTI ...
- log4net 一分钟上手
1. 首先从apache网站下载log4net, http://logging.apache.org/log4net/download_log4net.cgi .我下的是最新版本 log4net- ...
- 微软VSS的超级BUG
发现问题:今天一个新同事,无意中发现他直接就登录进VSS了,并且还是“admin”用户: 解决问题:于是开始在网上找度娘和谷歌帮忙,真是不查不要紧,一查吓一跳,VSS本身就存在这个bug,并且是一个超 ...
- lintcode:最大间隔
题目 给定一个未经排序的数组,请找出其排序表中连续两个要素的最大间距. 如果数组中的要素少于 2 个,请返回 0. 注意事项 可以假定数组中的所有要素都是非负整数,且最大不超过 32 位整数. 样例 ...
- 使用XShell工具密钥认证登录Linux系统
如果你是一名Linux运维,那么Linux服务器的系统安全问题,可能是你要考虑的,而系统登录方式有两种,密码和密钥.哪一种更加安全呢? 无疑是后者! 这里我为大家分享用Xshell利器使用密钥的方式登 ...
- win7 安装Redis
1.下载Redis的压缩包 https://github.com/dmajkic/redis/downloads 我下载的是redis-2.4.5-win32-win64.zip 下载完后将其解压放在 ...