Visual C# 2.0泛型编程基础

来源:互联网 发布:淘宝女士羽绒服 编辑:程序博客网 时间:2024/06/05 00:41

我们再来看泛型方法,C#的泛型机制只支持在方法申明上包含类型参数,也即是泛型方法。特别注意的是,泛型不支持在除了方法以外的其他类/接口成员上使用类型参数,但这些成员可以被包含在泛型类型中,并且可以使用泛型类型的类型参数。还有一点需要说的就是,泛型方法可以在泛型类型中,也可以存在于非泛型类型中。下面我们分别看一下泛型类型的申明,调用,重载和覆盖。

using System;
using System.Collections.Generic;
using System.Text;

namespace GenericTest
{
 class GenericClass
 {
  //申明一个泛型方法
  public T getvalue<T>(T t)
  {
   return t;
  }

  //调用泛型方法
  //注意:在调用泛型方法时,对泛型方法的类型参数实例化
  public int useMethod()
  {
   return this.getvalue<int>(10);
  }

  //重载getvalue方法
  public int getvalue(int i)
  {
   return i;
  }
 }

 //下面演示覆盖
 //要注意的是,泛型方法被覆盖时,约束被默认继承,不需要重新指定约束关系
 abstract class Parent
 {
  public abstract K TEST<K, V>(K k, V v) where K : V;
 }

 class Child : Parent
 {
  public override T TEST<T, S>(T t, S s)
  {
   return t;
  }
 }
}
  最后我们来看一下泛型中的约束:

  C#中的泛型只支持显示的约束,因为这样才能保证C#所要求的类型安全,但显示的约束并非时必须的,如果不加约束,泛型类型参数将只能访问System.Object类型中的公有方法。“显式约束”由where子句表达,可以指定“基类约束”,“接口约束”,“构造器约束”,“值类型/引用类型约束”共四种约束。下面的例子来源于李建忠老师的讲座PPT。

  1、基类约束:

class A { public void F1() {} }
class B { public void F2() {} }
class C<S,T>
where S: A // S继承自A
where T: B // T继承自B
{
 // 可以在类型为S的变量上调用F1,
 // 可以在类型为T的变量上调用F2
}
  2、接口约束

interface IPrintable { void Print(); }
interface IComparable<T> { int CompareTo(T v);}
interface IKeyProvider<T> { T GetKey(); }
class Dictionary<K,V>
where K: IComparable<K>
where V: IPrintable, IKeyProvider<K>
{
 // 可以在类型为K的变量上调用CompareTo,
 // 可以在类型为V的变量上调用Print和GetKey
}
  3、构造器约束

class A { public A() { } }
class B { public B(int i) { } }
class C<T>
where T : new()
{
 //可以在其中使用T t=new T();
}
C<A> c=new C<A>(); //可以,A有无参构造器
C<B> c=new C<B>(); //错误,B没有无参构造器
  4、值/引用类型约束

public struct A { }
public class B { }
class C<T>
where T : struct
{
 // T在这里面是一个值类型
}
C<A> c=new C<A>(); //可以,A是一个值类型
C<B> c=new C<B>(); //错误,B是一个引用类型

我们再来看泛型方法,C#的泛型机制只支持在方法申明上包含类型参数,也即是泛型方法。特别注意的是,泛型不支持在除了方法以外的其他类/接口成员上使用类型参数,但这些成员可以被包含在泛型类型中,并且可以使用泛型类型的类型参数。还有一点需要说的就是,泛型方法可以在泛型类型中,也可以存在于非泛型类型中。下面我们分别看一下泛型类型的申明,调用,重载和覆盖。

using System;
using System.Collections.Generic;
using System.Text;

namespace GenericTest
{
 class GenericClass
 {
  //申明一个泛型方法
  public T getvalue<T>(T t)
  {
   return t;
  }

  //调用泛型方法
  //注意:在调用泛型方法时,对泛型方法的类型参数实例化
  public int useMethod()
  {
   return this.getvalue<int>(10);
  }

  //重载getvalue方法
  public int getvalue(int i)
  {
   return i;
  }
 }

 //下面演示覆盖
 //要注意的是,泛型方法被覆盖时,约束被默认继承,不需要重新指定约束关系
 abstract class Parent
 {
  public abstract K TEST<K, V>(K k, V v) where K : V;
 }

 class Child : Parent
 {
  public override T TEST<T, S>(T t, S s)
  {
   return t;
  }
 }
}
  最后我们来看一下泛型中的约束:

  C#中的泛型只支持显示的约束,因为这样才能保证C#所要求的类型安全,但显示的约束并非时必须的,如果不加约束,泛型类型参数将只能访问System.Object类型中的公有方法。“显式约束”由where子句表达,可以指定“基类约束”,“接口约束”,“构造器约束”,“值类型/引用类型约束”共四种约束。下面的例子来源于李建忠老师的讲座PPT。

  1、基类约束:

class A { public void F1() {} }
class B { public void F2() {} }
class C<S,T>
where S: A // S继承自A
where T: B // T继承自B
{
 // 可以在类型为S的变量上调用F1,
 // 可以在类型为T的变量上调用F2
}
  2、接口约束

interface IPrintable { void Print(); }
interface IComparable<T> { int CompareTo(T v);}
interface IKeyProvider<T> { T GetKey(); }
class Dictionary<K,V>
where K: IComparable<K>
where V: IPrintable, IKeyProvider<K>
{
 // 可以在类型为K的变量上调用CompareTo,
 // 可以在类型为V的变量上调用Print和GetKey
}
  3、构造器约束

class A { public A() { } }
class B { public B(int i) { } }
class C<T>
where T : new()
{
 //可以在其中使用T t=new T();
}
C<A> c=new C<A>(); //可以,A有无参构造器
C<B> c=new C<B>(); //错误,B没有无参构造器
  4、值/引用类型约束

public struct A { }
public class B { }
class C<T>
where T : struct
{
 // T在这里面是一个值类型
}
C<A> c=new C<A>(); //可以,A是一个值类型
C<B> c=new C<B>(); //错误,B是一个引用类型  
原创粉丝点击