视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
.NET基础之自定义泛型分析
2020-11-27 22:38:44 责编:小采
文档


本文实例分析了.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程序设计有所帮助。

下载本文
显示全文
专题