当前位置: 移动技术网 > IT编程>开发语言>.net > .NET基础之自定义泛型分析

.NET基础之自定义泛型分析

2017年12月12日  | 移动技术网IT编程  | 我要评论

刀剑神域h,天宝纪事,极品钢琴游戏

本文实例分析了.net基础之自定义泛型。分享给大家供大家参考。具体分析如下:

在.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();
        }
}

希望本文所述对大家的.net程序设计有所帮助。

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网