欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

.NET基础之自定义泛型

程序员文章站 2023-12-24 16:21:51
在.net中泛型使用非常频繁,在控制台应用程序中,默认的引入了system.collection.generics名称空间,其中就提供了我们经常使用的泛型:list
在.net中泛型使用非常频繁,在控制台应用程序中,默认的引入了system.collection.generics名称空间,其中就提供了我们经常使用的泛型:list<t>和dictionary<t>,相信用过它们的都知道它们的强大。还有一种我们经常使用的简单的泛型:system.nullable<t>,即可空类型。我们可以:

 

system.nullable<int> nullableint;

声明一个可空的int类型,由于c#语法对这个做了简化通常我们都不这样写,而是这样写:

 

int? nullableint

下面重点介绍一下如何自定义泛型。

 

 

 

定义泛型类

 

创建泛型类是需要在类定义中用尖括号语法:

 

class mygenericclass<t>

{

    ...

}

t可以是任意的标示符,只要遵守命名规则即可。

 

 

 

可以把类型用在类成员的返回类型,方法参数类型等,例如:

 

复制代码

class mygenericclass<t1, t2, t3>

{

    private t1 t1object;

 

    public mygenericclass(t1 item)

    {

        t1object = item;

    }

 

    public t1 t1object

    {

        get

        {

            return t1object;

        }

    }

}

复制代码

注意如果不能假定提供了什么类型。下面的代码不能执行:

 

复制代码

class mygenericclass<t1, t2, t3>

{

    private t1 t1object;

 

    public mygenericclass()

    {

        t1object = new t1();

    }

}

复制代码

因为我们不知道t1是否有公有的默认构造函数。

 

 

 

default关键字

 

如果我们定义了一个泛型的字段,我们想在构造函数中初始化它,但是我们不知道它的引用类型还是值类型,那么default就派上用处了:

 

public mygenericclass()

{

    t1object = default(t1);

}

如果是值类型就赋值0,引用类型就赋值null。

 

 

 

约束类型

 

在定义泛型的时候我们可以对类型进行约束,通过where关键字实现:

 

class mygenericclass<t1> where t : constraint1,constraint

{

    ...

}

constraint定义了约束,多个约束用逗号隔开,如果有多个类型:

 

class mygenericclass<t1, t2> where t1 : constraint1 where t2 : constraint

{

    ...

}

下面给出一些可用的约束

 

                                        约束                                                                  说明

 

                                where t:struct                                     使用结构约束,类型t必须是值类型

 

                                where t:calss                                       类约束指定,类型t必须是引用类型

 

                                where t:interface                                  指定类型t必须实现是接口或者实现了接口

 

                                where t:base-class                               指定类型t必须是基类或者派生于基类

 

                               where t:new()                                       指定类型t必须有一个默认构造函数

 

 

 

下面结合以上知识给个实例:(ps不要看到代码多 其实很简单的 耐心看下去)

 

先定义四个类animal、cow 、chicken和supercow

 

复制代码

#region animal 虚基类 有一个name属性 feed方法和一个虚方法makeanoise

    //虚基类 有一个name属性 feed方法和一个虚方法makeanoise

    public abstract class animal

    {

        protected string name;

 

        public string name

        {

            get

            {

                return name;

            }

            set

            {

                name = value;

            }

        }

 

        public animal()

        {

            name = "the animal with no name";

        }

 

        public animal(string newname)

        {

            name = newname;

        }

 

        public void feed()

        {

            console.writeline("{0} has been fed.", name);

        }

 

        public abstract void makeanoise();

    }

    #endregion

复制代码

复制代码

//cow animal的子类,实现虚方法

    public class cow:animal

    {

        public cow(string name) :

            base(name)

        {

        }

        public override void makeanoise()

        {

            console.writeline("{0} says 'moo!'", name);

        }

    }

复制代码

复制代码

//chicken类,animal子类

    public class chicken:animal

    {

        public chicken(string name)

            : base(name)

        { }

        public override void makeanoise()

        {

            console.writeline("{0} says 'cluck'", name);

        }

    }

复制代码

复制代码

//cow的子类,有一个自己的方法fly

    class supercow : cow

    {

        public supercow(string name) : base(name) 

        {

        }

 

        public void fly()

        {

            console.writeline("{0} is flying!", name);

        }

 

        public override void makeanoise()

        {

            console.writeline("{0} says 'i am supercow!'", name);

        }

 

    }

复制代码

类准备好了之后,我们可以开始定义我们的泛型了:

 

复制代码

//继承了迭代器接口,这样方便使用foreach 约束它的类型为animal及其子类

    public class farm<t>:ienumerable<t> where t : animal

    {

        private list<t> animals = new list<t>();

 

        public list<t> animals

        {

            get 

            {

                return animals;    

            }

        }

        //迭代器

        public ienumerator<t> getenumerator()

        {

            return animals.getenumerator();

        }

 

        ienumerator ienumerable.getenumerator()

        {

            return animals.getenumerator();

        }

 

        //执行所有animal的makeanoise()

        public void makenoises()

        {

            foreach (t animal in animals)

            {

                animal.makeanoise();

            }

        }

        //执行所有animal的feed()

        public void feedtheanimals()

        {

            foreach (t animal in animals)

            {

                animal.feed();

            }

        }

        //获得animals中的cow

        public farm<cow> getcows()

        {

            farm<cow> cowfarm = new farm<cow>();

            foreach (t animal in animals)

            {

                if (animal is cow)

                {

                    cowfarm.animals.add(animal as cow);

                }

            }

            return cowfarm;

        }

    }

复制代码

泛型定义好了,我们用写代码来调用它:

 

复制代码

class program

    {

        static void main(string[] args)

        {

            farm<animal> farm = new farm<animal>();

            farm.animals.add(new cow("jack"));

            farm.animals.add(new chicken("vera"));

            farm.animals.add(new chicken("sally"));

            farm.animals.add(new supercow("kevin"));

            farm.makenoises();

 

            farm<cow> dairyfarm = farm.getcows();

            dairyfarm.feedtheanimals();

 

            foreach (cow cow in dairyfarm)

            {

                if (cow is supercow)

                {

                    (cow as supercow).fly();

                }

            }

            console.readkey();

        }

    }

上一篇:

下一篇: