C#个人总结,第5章:泛型
2014-09-28 16:57
253 查看
1. 概述
(1)泛型并不是一个全新的结构,其他语言中有类似的概念。例如,C++模板就与泛型相似。1.1 性能
(1)对值类型使用非泛型集合类,在把值类型转换为引用类型,和把引用类型转换为值类型时,需要进行装箱和拆箱操作。(2)值类型存储在栈上,引用类型存储在堆上。C#类是引用类型,结构是值类。
(3)从值类型转换为引用类型称为装箱。
1.2 类型安全
1.3 二进制代码的重用
1.4 代码的扩展
1.5 命名约定
泛型类型的名称用字母T作为前缀。如果没有特殊的要求,泛型类型允许用任意类替代,且只使用了一个泛型类型,就可以用字符T作为泛型类型的名称。
如果泛型类型有特定的要求(例如,它必须实现一个接口或派生自鞠,或者使用了两个或多个泛型类型,就应给泛型类型使用描述性的名称:
2. 创建泛型类
(1)一个一般的、非泛型的简化链表类,在链表中,一个元素引用下一个元素代码:
namespace study5_2
{
//链表结点,包括前一个指针,后一个指针,以及当前值
public class LinkedListNode
{
public object Value { get; private set; }
public LinkedListNode Next { get; internal set; }
public LinkedListNode Prev { get; internal set; }
public LinkedListNode(object value)
{
this.Value = value;
}
}
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;
newNode.Prev = Last;
Last = First;
}
else
{
LinkedListNode previous = Last;
Last.Next = newNode;
Last = newNode;
Last.Prev = previous;
}
return newNode;
}
public IEnumerator GetEnumerator()
{
LinkedListNode current = First;
while(current!=null)
{
yield return current.Value;
current = current.Next;
}
}
}
class Program
{
static void Main(string[] args)
{
var list1 = new LinkedList();
list1.AddLast(2);
list1.AddLast(4);
list1.AddLast("6");
foreach (int i in list1)
{
Console.WriteLine(i);
}
}
}
}
结果:
(2)链表的泛型版本:
代码:
namespace study5_2
{
//链表结点,包括前一个指针,后一个指针,以及当前值
public class LinkedListNode<T>
{
public T Value { get; private set; }
public LinkedListNode<T> Next { get; internal set; }
public LinkedListNode<T> Prev { get; internal set; }
public LinkedListNode(T value)
{
this.Value = value;
}
}
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;
newNode.Prev = Last;
Last = First;
}
else
{
LinkedListNode<T> previous = Last;
Last.Next = newNode;
Last = newNode;
Last.Prev = previous;
}
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();
}
}
class Program
{
static void Main(string[] args)
{
var list1 = new LinkedList<int>();
list1.AddLast(2);
list1.AddLast(4);
list1.AddLast(6);
foreach (int i in list1)
{
Console.WriteLine(i);
}
}
}
}
结果:
3. 泛型类的功能
(1)代码namespace study5_3
{
public interface IDocument
{
string Title { get; set; }
string Content { get; set; }
}
public class Document:IDocument
{
public string Title { get; set; }
public string Content { get; set; }
public Document()
{
}
public Document(string title, string content)
{
this.Title = title;
this.Content = content;
}
}
public class DocumentManager<T>
{
private readonly Queue<T> documentQueue = new Queue<T>();
public void AddDocument(T doc)
{
lock(this)
{
documentQueue.Enqueue(doc);
}
}
public bool IsDocumentAvailable
{
get { return documentQueue.Count > 0; }
}
public T GetDocument()
{
T doc = default(T);
lock(this)
{
doc = documentQueue.Dequeue();
}
return doc;
}
public void DisplayAllDocuments()
{
foreach(T doc in documentQueue)
{
Console.WriteLine(((IDocument)doc).Title);
}
}
}
class Program
{
static void Main(string[] args)
{
var dm = new DocumentManager<Document>();
dm.AddDocument(new Document("Title A", "Sample A"));
dm.AddDocument(new Document("Title B", "Sample B"));
dm.DisplayAllDocuments();
if(dm.IsDocumentAvailable)
{
Document d = dm.GetDocument();
Console.WriteLine(d.Content);
}
}
}
}
(2)结果
3.1 默认值
(1)现在给DocumentManager<T>添加一个GetDocument()方法。在这个方法中,应把类型T指定为null。但是,不能把null 赋予泛型类型。原因是泛型类型也可以实例化为值类型,而null只能用于引用类型。为了解决这个问题,可以使用default关键字。通过default关键字,将null赋予引用类型,将0赋予值类型。3.2 约束
(1)泛型支持几种约束类型3.3 继承
(1)泛型类型可以实现泛型接口,也可以派生自一个类。泛型类可以派生自泛型基类:public class Base<T>
{
}
public class Derived<T> : Base<T>
{
}
3.4 静态成员
(1)泛型类的静态成员只能在类的一个实例中共享。下面StaticDemo<T>类包含静态字段x:public class StaticDemo<T>
{
public static int x;
}
4. 泛型接口
(1)使用泛型可以定义接口,在按口中定义的方法可以带泛型参数。4.1 协变和抗变
(1).NET4通过协变和抗变为泛型接口和泛型委托添加了一个重要的扩展。协变和抗变指对参数和返回值的类型进行转换。4.2 泛型接口的协变
(1)如果泛型类型用out关键字标注,泛型接口就是协变的。这也意味着返回类型只能是T。public interface IIndex<out T>
{
T this[int index] { get; }
int Count { get; }
}
4.3 泛型接口的抗变
PS:对泛型结构了解还不深,希望大家能够帮助我多了解了解,谢谢。小结:
(1)泛型类似于一个模板。在把值类型转换为引用类型,和把引用类型转换为值类型时,需要进行装箱和拆箱操作。
(2)代码1:
namespace restudy5_1_2
{
class Program
{
static void Main(string[] args)
{
var list = new ArrayList();
list.Add(123);
list.Add("aaa");
list.Add("monb");
foreach (var i in list)
{
Console.WriteLine(i);
}
}
}
}
相关文章推荐
- C#集合,泛型,以及自定义排序自己总结1
- C# 高级编程 第5章 数组 总结
- C#中的泛型程序设计总结
- C#个人总结:第一章,.NET 体系结构
- C# 泛型List<T>学习总结
- C# 中的泛型总结
- C#中yield关键字的使用个人总结
- 黑马程序员--Java基础加强--14.利用反射操作泛型III【解析关于泛型类型的细节信息的获取方法】【Method与泛型相关的方法】【个人总结】
- 黑马程序员--Java基础加强--13.利用反射操作泛型II【TypeVariable】【GenericArrayType】【WildcardType】【Type及其子接口的来历】【个人总结】
- C#个人总结,第4章:继承
- 黑马程序员_学习日记7_C#基础归纳总结之泛型
- 黑马程序员--08.泛型--02.【泛型方法】【泛型接口】【泛型限定的基本使用】【个人总结】
- C# 泛型学习总结
- 黑马程序员--Java基础加强--16.利用反射操作泛型V【通过Constructor反射解析泛型构造方法】【通过Field反射解析泛型成员变量】【个人总结】
- 黑马程序员--Java基础加强--05.【泛型通配符】【个人总结】
- C#泛型编程基础知识总结
- C#中委托和事件机制(续)(个人总结)
- 黑马程序员--Java基础加强--03.代码简化 书写规律II_参数化数据类型【重载】【多态】【泛型】【泛型限定】【个人总结】
- C#开发规范总结(个人建议)
- C#个人总结,第6章:数组