zl程序教程

您现在的位置是:首页 >  后端

当前栏目

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

Net基础泛型 分析 自定义
2023-06-13 09:15:31 时间

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

在.NET中泛型使用非常频繁,在控制台应用程序中,默认的引入了System.Collection.Generics名称空间,其中就提供了我们经常使用的泛型:List<T>和Dictionary<T>,相信用过它们的都知道它们的强大。还有一种我们经常使用的简单的泛型:System.Nullable<T>,即可空类型。我们可以:
 
System.Nullable<int>nullableInt;
声明一个可空的int类型,由于C#语法对这个做了简化通常我们都不这样写,而是这样写:
 
int?nullableInt
下面重点介绍一下如何自定义泛型。
 
定义泛型类
 
创建泛型类是需要在类定义中用尖括号语法:

复制代码代码如下:
classMyGenericClass<T>
{
   ...
}

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

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

复制代码代码如下:
classMyGenericClass<T1,T2,T3>
{
   privateT1t1Object;
 
   publicMyGenericClass(T1item)
   {
       t1Object=item;
   }
 
   publicT1T1Object
   {
       get
       {
           returnt1Object;
       }
   }
}

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

复制代码代码如下:classMyGenericClass<T1,T2,T3>
{
   privateT1t1Object;
 
   publicMyGenericClass()
   {
       t1Object=newT1();
   }
}

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

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

复制代码代码如下:publicMyGenericClass()
{
   t1Object=default(T1);
}
如果是值类型就赋值0,引用类型就赋值null。

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

复制代码代码如下:classMyGenericClass<T1>whereT:constraint1,constraint
{
   ...
}
constraint定义了约束,多个约束用逗号隔开,如果有多个类型:
复制代码代码如下:classMyGenericClass<T1,T2>whereT1:constraint1whereT2:constraint
{
   ...
}
下面给出一些可用的约束
 
                                       约束                                                                 说明
 
                               whereT:struct                                    使用结构约束,类型T必须是值类型
 
                               whereT:calss                                      类约束指定,类型T必须是引用类型
 
                               whereT:interface                                 指定类型T必须实现是接口或者实现了接口
 
                               whereT:base-class                              指定类型T必须是基类或者派生于基类
 
                              whereT:new()                                      指定类型T必须有一个默认构造函数
 
 
 
下面结合以上知识给个实例:(PS不要看到代码多其实很简单的耐心看下去)
 
先定义四个类Animal、Cow、Chicken和SuperCow
复制代码代码如下:#regionAnimal虚基类有一个name属性Feed方法和一个虚方法MakeANoise
//虚基类有一个name属性Feed方法和一个虚方法MakeANoise
publicabstractclassAnimal
{
       protectedstringname;
 
       publicstringName
       {
           get
           {
               returnname;
           }
           set
           {
               name=value;
           }
       }
 
       publicAnimal()
       {
           name="Theanimalwithnoname";
       }
 
       publicAnimal(stringnewName)
       {
           name=newName;
       }
 
       publicvoidFeed()
       {
           Console.WriteLine("{0}hasbeenfed.",name);
       }
 
       publicabstractvoidMakeANoise();
}
#endregion

//CowAnimal的子类,实现虚方法
publicclassCow:Animal
{
       publicCow(stringname):
           base(name)
       {
       }
       publicoverridevoidMakeANoise()
       {
           Console.WriteLine("{0}says"moo!"",name);
       }
}

//Chicken类,Animal子类
publicclassChicken:Animal
{
       publicChicken(stringname)
           :base(name)
       {}
       publicoverridevoidMakeANoise()
       {
           Console.WriteLine("{0}says"cluck"",name);
       }
}

//Cow的子类,有一个自己的方法Fly
classSuperCow:Cow
{
       publicSuperCow(stringname):base(name)
       {
       }
 
       publicvoidFly()
       {
           Console.WriteLine("{0}isflying!",name);
       }
 
       publicoverridevoidMakeANoise()
       {
           Console.WriteLine("{0}says"Iamsupercow!"",name);
       }
}

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

复制代码代码如下://继承了迭代器接口,这样方便使用Foreach约束它的类型为Animal及其子类
publicclassFarm<T>:IEnumerable<T>whereT:Animal
{
       privateList<T>animals=newList<T>();
 
       publicList<T>Animals
       {
           get
           {
               returnanimals;   
           }
       }
       //迭代器
       publicIEnumerator<T>GetEnumerator()
       {
           returnanimals.GetEnumerator();
       }
 
       IEnumeratorIEnumerable.GetEnumerator()
       {
           returnanimals.GetEnumerator();
       }
 
       //执行所有animal的MakeANoise()
       publicvoidMakeNoises()
       {
           foreach(Tanimalinanimals)
           {
               animal.MakeANoise();
           }
       }
       //执行所有animal的Feed()
       publicvoidFeedTheAnimals()
       {
           foreach(Tanimalinanimals)
           {
               animal.Feed();
           }
       }
       //获得animals中的cow
       publicFarm<Cow>GetCows()
       {
           Farm<Cow>cowFarm=newFarm<Cow>();
           foreach(Tanimalinanimals)
           {
               if(animalisCow)
               {
                   cowFarm.Animals.Add(animalasCow);
               }
           }
           returncowFarm;
       }
}

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

复制代码代码如下:classProgram
{
       staticvoidMain(string[]args)
       {
           Farm<Animal>farm=newFarm<Animal>();
           farm.Animals.Add(newCow("Jack"));
           farm.Animals.Add(newChicken("Vera"));
           farm.Animals.Add(newChicken("Sally"));
           farm.Animals.Add(newSuperCow("Kevin"));
           farm.MakeNoises();
 
           Farm<Cow>dairyFarm=farm.GetCows();
           dairyFarm.FeedTheAnimals();
 
           foreach(CowcowindairyFarm)
           {
               if(cowisSuperCow)
               {
                   (cowasSuperCow).Fly();
               }
           }
           Console.ReadKey();
       }
}

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