C# 语法之泛型

一.什么是泛型

  泛型其实就是一个不确定的类型,可以在类或方法上使用。泛型在声明期间没有明确定义类型,编译后生成一个占位符,只有在调用后传入类型,才会将该确切的类型将占位符替换掉。

二.泛型的定义

//用在类中
public class ClassName<CName>
{
    //用在方法中
    public void Mothed<MName>() {
        
    }

    //泛型类中具体使用CName
    //返回值为CName并且接受一个类型为CName类型的对象
    public CName GetC(CName c) {

    }
}

  这里的CName和MName是可变的类型(名字也是可变),可以让调用者来决定要使用的类型。

三.使用

  下面举个例子。

public class Animal
{
    //会跑的方法
    public virtual void CanRun()
    {
        Console.WriteLine("Animal Run Can");
    }
}

public class Dog : Animal
{
    //重写父类方法
    public override void CanRun()
    {
        Console.WriteLine("Dog Can Run");
    }
}

public class Cat : Animal
{
    //重写父类方法
    public override void CanRun()
    {
        Console.WriteLine("Cat Can Run");
    }
}

  再定义一个animalHouse来存放所有的动物。

public class AnimalHouse
{
    private List<Animal> animals = new List<Animal>();

    //添加方法
    public void AddAnimal(Animal a)
    {
        animals.Add(a);
    }
}

  AnimalHouse可以存放所有的动物,但如果取出来,使用就有些不方便。现在放进去Dog和Cat,你可以将所有动物都带出来跑步。假如Dog有个方法是Canswin()游泳的方法,那这里是调用不了,animal没有这个方法。

  如果使用泛型的话,就可以由调用者决定使用哪种类型。在AnimalHouse将所有animal改为泛型。

public class AnimalHouse<T>
{
    private List<T> animals = new List<T>();

    //添加方法
    public void AddAnimal(T a)
    {
        animals.Add(a);
    }
}

  AnimalHouse想存放什么类型,由调用者决定。

//声明存放所有Dog类型的集合
AnimalHouse<Dog> dog = new AnimalHouse<Dog>();
//声明存放所有Cat类型的集合
AnimalHouse<Cat> cat = new AnimalHouse<Cat>();

  传入哪个类型,原本的T就会编译成具体的类型。animalHouse可以让我们来自己构造存放哪种动物的集合。该集合就可以具体使用集合中动物特有的方法。

  这里还有个问题,原本AnimalHouse只能存放animal,现在是泛型T,那就算是非animal的类也可以存进去,不符合最初的设计。所以为了类型安全,需要对传入的类型进行约束。

四.泛型约束

  泛型约束就是对泛型(传入的类型)进行约束,约束就是指定该类型必须满足某些特定的特征,例如可以被实例化,实现Animal类等。举个例子。

class Base { }
class Test<T, U>
    where U : struct
    where T : Base, new()
{ }

  使用的话,只需要在泛型后面加上where来使用。

  where T : struct。类型必须为值类型。

  where T : class。类型必须为引用类型。

  where T : new()。类型参数必须具有公共无参数构造函数。 与其他约束一起使用时,new() 约束必须最后指定。

  where T : <基类名>。类型参数必须是指定的基类或派生自指定的基类。

  where T : <接口名称>。类型参数必须是指定的接口或实现指定的接口。 可指定多个接口约束。 约束接口也可以是泛型。

  然后,我们来为AnimalHouse添加泛型约束为:必须包含公共无参构造函数和基数必须为Animal。

//Animal约束T必须是Animal的子类或者本身,new()约束放在最后
public class AnimalHouse<T> where T : Animal, new()
{
    private List<T> animals = new List<T>();

    //添加方法
    public void AddAnimal(T a)
    {
        //调用CanRun方法
        //如果不加Animal泛型约束是无法调用.CanRun方法的,因为类型是不确定的
        a.CanRun();

        animals.Add(a);
    }
}

  现在AnimalHouse类限制要传入的参数是,必须继承Animal,且有公共无参构造函数的。

 

上一篇:报错:java.net.UnknownHostException: iMac: nodename nor servname provided, or not known


下一篇:maven-install打包错误:No compiler is provided in this environment. Perhaps you are running on a JRE rath