C# 2.0 - 泛型(Generics)

除非必要,否则请不要使用泛型(Generics)!
滥用泛型只会增加代码的复杂性。

有如“Hello, World!”一样,说到泛型必定从Stack说起,先看看。

public class Stack <T>
{
  public void Push(T item)
  {...}

  public T Pop()
  {...}
}

Stack<int> stack = new Stack<T>();
stack.Push(12);
int i = stack.Pop();

注:微软中文文档中把T翻译为“一般类型参数”。???我觉得还是翻译为“类型参数”更合适些。

如果你熟悉 .net Framework 的容器类,必定能感觉到泛型带来的好处。
1. 同样支持任意类型,包括引用类型和值类型。
2. 实现了类型安全检查,包括IDE编码检查和编译器检查。
3. 避免了值类型的装箱和拆箱,提高了性能。

泛型的好处

(摘自MSDN China)
.NET 中的泛型使您可以重用代码以及在实现它时付出的努力。类型和内部数据可以在不导致代码膨胀的情况下更改,而不管您使用的是值类型还是引用类型。您可以一次性地开发、测试和部署代码,通过任何类型(包括将来的类型)来重用它,并且全部具有编译器支持和类型安全。因为一般代码不会强行对值类型进行装箱和取消装箱,或者对引用类型进行向下强制类型转换,所以性能得到显著提高。对于值类型,性能通常会提高 200%;对于引用类型,在访问该类型时,可以预期性能最多提高 100%(当然,整个应用程序的性能可能会提高,也可能不会提高)。

泛型同样适用于Struct

public struct Pos <T>
{
  public T x;
  public T y;
}

多个类型参数

public class List<K, T>
{
  public void Add(K key, T value)
  {...}

  public T Items[K key]
  {
    get {...}
  }
}

List<string, int> list = new List<string, int>();
list.Add("a", 1);
Console.WriteLine(list["a"]);

派生约束
有些时候我们需要对类型参数进行约束,比如要求T必须实现某个接口或者继承自某个类,以便我们在方法中调用某个方法。

public class Class1<T> where T : IComparable
{
  public void Method(T t)
  {
    t.CompareTo(...);
  }
}

public class Class2<K, T> : ClassX
  where T : ClassX, IComparable
  where K : IComparable
{
  public void Method(T t)
  {
    t.CompareTo(...);
  }
}

构造函数约束
要求类型参数必须拥有默认构造方法,以便我们在泛型类中创建该类型对象。

public class GenericsClass <T>
  where T : new()
{
}

引用/值类型约束
要求类型参数必须是值类型或者引用类型。

public class GenericsClass<T>
  where T : struct
  where K : class
{
}

泛型和强制类型转换
编译器允许您将类型参数显式强制转换到其他任何接口,但不能将其转换到类。

class MyClass <T>
{
  void SomeMethod(T t)
  {
    ISomeInterface obj1 = (ISomeInterface)t;//Compiles
    SomeClass obj2 = (SomeClass)t; //Does not compile
  }
}
但是,您可以使用临时的 Object 变量,将类型参数强制转换到其他任何类型。

class MyClass<T>
{
  void SomeMethod(T t)
  {
    object temp = t;
    SomeClass obj = (SomeClass)temp;
  }
}
这样的显式强制类型转换是危险的,因为如果为取代类型参数而使用的类型实参不是派生自您要显式强制转换到的类型,则可能在运行时引发异常。要想不冒引发强制类型转换异常的危险,一种更好的办法是使用 is 和 as 运算符。

public class MyClass <T>
{
  public void SomeMethod(T t)
  {
    if(t is int)
    {...}

    if(t is LinkedList)
    {...}

    string str = t as string;
    if(str != null)
    {...}

    LinkedList list = t as LinkedList;
    if(list != null)
    {...}
  }
}
 

时间: 2024-08-07 03:40:51

C# 2.0 - 泛型(Generics)的相关文章

.NET2.0泛型的“近距离”实践

早闻.NET 2.0中泛型的大名,但一直未在实际开发中使用.最近在开发公司项目程序的过程中体验了一下. 应用场景: 在配置文件中通过反序列化读取相应的邮件设置. 配置文件示例: <BlogConfigurationSettings><MailSettings><MailSetting Name="ApproveEmail" SmtpServer="smtp.126.com" EmailFrom="" UserName

.NET 2.0 泛型在实际开发中的一次小应用

早闻.NET 2.0中泛型的大名,但一直未在实际开发中使用. 最近在开发博客园网站程序的过程中体验了一下. 应用场景: 在配置文件中通过反序列化读取相应的邮件设置. 配置文件示例: <BlogConfigurationSettings><MailSettings>      <MailSetting Name="ApproveEmail" SmtpServer="smtp.126.com" EmailFrom=""

使用C# 2.0泛型实现单例模式重用

介绍 很多有着不同开发背景得人都会比较熟悉单例模式.他们会发现每次他们要创建一个不同的单例类的时候,都不得不写同样得代码.使用新的C# 2.0的泛型,可以实现只写一次同样得代码. 使用 C# 2.0 泛型来完成单例模式的重用 使用 C# 2.0 的泛型,使得实现我所说的"单例提供者"成为可能.这是一个可用来创建单例类实例确不需要为每个特定的类重写单例模式代码的可重用的类.这样分离出单例结构的代码,将有利于保持按单例模式使用类或不按单例模式使用类的灵活性. public sealed c

swift-Swift 2.0泛型例子解答

问题描述 Swift 2.0泛型例子解答 func anyCommonElements (lhs: T, _ rhs: U) -> Bool { for lhsItem in lhs { for rhsItem in rhs { if lhsItem == rhsItem { return true } } } return false } anyCommonElements([1, 2, 3], [3]) 练习: 修改anyCommonElements(_:_:)函数来创建一个函数,返回一个数

网络编程经验技巧:ASP.NET2.0泛型和匿名方法

asp.net|编程|技巧|网络 泛型: 泛型概述:泛型可应用于类.方法.结构.接口.委托等设计中,兼复用性.类型安全和高效率于一身是与之对就的非泛型所不及的应用泛型,必须使用类System.Collections.Generic.Stack.该类的声明方式如下: System.Collections.Generic.Stack (声明代码) 可以把Stack类想像成具有如下示意性处理过程: Stack类示意性代码: public class stack<> { T[] item; int c

C#2.0泛型学习--入门篇

     最近频繁的接触到泛型方面的问题,所以也不得不来学习一下了,开始主要是在MSDN的WebCast上去下载教学录象看的(李建忠老师的),本篇文章先介绍一下泛型入门方面的知识,希望能让刚开始学习泛型的朋友能够更快的入门,言归正传,首先我们来看一下泛型的基本概念:      最显著的一点就是它参数化了类型,把类型作为参数抽象出来,从而使我们在实际的运用当中能够更好的实现代码的重复利用,同时它提供了更强的类型安全,更高的效率,不过在约束方面,它只支持显示的约束,这样在灵活性方面就显得不是那么好了

ASP.NET 2.0泛型和匿名方法

泛型: 泛型概述:泛型可应用于类.方法.结构.接口.委托等设计中,兼复用性.类型安全和高效率于一身是与之对就的非泛型所不及的应用泛型,必须使用类System.Collections.Generic.Stack.该类的声明方式如下: System.Collections.Generic.Stack (声明代码) 可以把Stack类想像成具有如下示意性处理过程: Stack类示意性代码: public class stack<> { T[] item; int count; public void

Jdk5.0新特性Generic Types(泛型)

1. 介绍 2.定义简单Java泛型 其实Java的泛型就是创建一个用类型作为参数的类.就象我们写类的方法一样,方法是这样的method(String str1,String str2 ),方法中参数str1.str2的值是可变的.而泛型也是一样的,这样写class Java_Generics<K,V>,这里边的K和V就象方法中的参数str1和str2,也是可变.下面看看例子: import java.util.Hashtable; class TestGen0<K,V>{ pub

c#v2.0 扩展特性 翻译(1)

Introduction to C# 2.0C# 2.0 introduces several language extensions, the most important of which are Generics, Anonymous Methods, Iterators, and Partial Types. C#2.0 介绍几种语言扩展,泛型,匿名方法,迭代器 和.partial Types. · Generics permit classes, structs, interfaces