Visual C# 2.0泛型编程基础

    技术2022-05-11  50

    我们再来看泛型方法,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是一个引用类型  

    最新回复(0)