最显著的一点就是它参数化了类型,把类型作为参数抽象出来,从而使我们在实际的运用当中能够更好的实现代码的重复利用,同时它提供了更强的类型安全,更高的
下面来看如何定义一个泛型类,很简单,你只需要意识到一点,在这里,类型已经被参数化了:
using System; using System.Collections.Generic; using System.Text; namespace GenericTest //调用泛型类中的 /**//// <summary> public Test(T Name,S Age) public void SetValue() |
上面的例子不是很恰当,目的是让初学泛型的你了解一下泛型的定义及实例化方法,如上,我们定义了一个泛型类,那么如何实现泛型类的继承呢?这里需要满足下面两点中的任何一点即可:
1、泛型类继承中,父类的类型参数已被实例化,这种情况下子类不一定必须是泛型类;
2、父类的类型参数没有被实例化,但来源于子类,也就是说父类和子类都是泛型类,并且二者有相同的类型参数;
//如果这样写的话,显然会报找不到类型T,S的错误 public class TestChild : Test<T, S> { } //正确的写法应该是 |
接着我们来看看泛型接口,其创建以及继承规则和上面说的泛型类是一样的,看下面的
public interface IList<T> { T[] GetElements(); } public interface IDictionary<K,V> { void Add(K key, V value); } // 泛型接口的类型参数要么已实例化 |
在来看一下泛型委托,首先我们定义一个类型参数为T的委托,然后在类中利用委托调用方法:
using System; using System.Collections.Generic; using System.Text; namespace GenericTest class test static void Main(string[] args) |
我们再来看泛型
using System; using System.Collections.Generic; using System.Text; namespace GenericTest //调用泛型方法 //重载getvalue方法 //下面演示覆盖 class Child : Parent |
最后我们来看一下泛型中的约束:
C#中的泛型只支持显示的约束,因为这样才能保证C#所要求的类型安全,但显示的约束并非时必须的,如果不加约束,泛型类型参数将只能
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是一个引用类型 |