版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、7.1 7.1 泛泛 型型7.2 7.2 反反 射射所谓泛型,是指通过参数化类型来实现在同一份代码所谓泛型,是指通过参数化类型来实现在同一份代码上操作多种数据类型,泛型编程是一种编程范式,它利用上操作多种数据类型,泛型编程是一种编程范式,它利用“参数化类型参数化类型”将类型抽象化,从而实现更为灵活的复用。将类型抽象化,从而实现更为灵活的复用。泛型类型和普通类型的区别在于泛型类型与一组类型参数泛型类型和普通类型的区别在于泛型类型与一组类型参数或类型变量关联。或类型变量关联。C#C#泛型能力是由泛型能力是由CLRCLR在运行时支持,区别于在运行时支持,区别于C+C+的编译的编译时模板机制和时模板机
2、制和JavaJava的编译时的的编译时的“搽拭法搽拭法”。这使得泛型能。这使得泛型能力可以在各个支持力可以在各个支持CLRCLR的语言之间进行无缝的互操作。的语言之间进行无缝的互操作。7.1.1 7.1.1 什么是泛型什么是泛型数据的抽象:数据的抽象:int MAX(int a,int b) return ab?a:b; double MAX1(double a,double b) return ab?a:b; int MAX(int a,int b) return ab?a:b; double MAX(double a,double b) return ab?a:b; 重载重载数据类型的抽象
3、:数据类型的抽象: T MAX(T a,T b) return ab?a:b; 泛型泛型int、double数据数据通常先声明泛型,然后通过类型实例化来使用泛型。通常先声明泛型,然后通过类型实例化来使用泛型。定义泛型的语法格式如下:定义泛型的语法格式如下:访问修饰符访问修饰符返回类型返回类型 泛型名称泛型名称其中,其中,“泛型名称泛型名称”要符合标识符的定义。尖括号要符合标识符的定义。尖括号表示类型参数列表,可以包含一个或多个类型参数,如表示类型参数列表,可以包含一个或多个类型参数,如。7.1.2 7.1.2 泛型的声明和使用泛型的声明和使用C#中常用的泛型有泛型类和泛型方法,例如:中常用的泛
4、型有泛型类和泛型方法,例如:class Stack/声明泛型类声明泛型类 T dataMaxSize;int top;void swap(ref T a,ref T b)/定义泛型方法定义泛型方法 T tmp = a;a = b;b = tmp;【例例7.1】 分析以下程序的执行结果。分析以下程序的执行结果。using System;namespace proj7_1 class Student /学生类学生类 int sno; /学号学号 string sname; /姓名姓名 public Student() public Student(int no, string name) sno
5、= no; sname = name; public void Dispstudent()/输出学生对象输出学生对象 Console.Write(0:1 ,sno,sname); class Teacher /教师类教师类 int tno; /编号编号 string tname; /姓名姓名 public Teacher() public Teacher(int no, string name) tno = no; tname = name; public void Dispteacher()/输出教师对象输出教师对象 Console.Write(0:1 , tno, tname); clas
6、s Stack/声明栈泛型类声明栈泛型类 int maxsize;/栈中元素最多个数栈中元素最多个数 T data;/存放栈中存放栈中T类型的元素类型的元素 int top;/栈顶指针栈顶指针 public Stack()/构造函数构造函数 maxsize = 10; data = new Tmaxsize; top = -1; public bool StackEmpty()/判断栈空方法判断栈空方法 return top = -1; public bool Push(T e)/元素元素e进栈方法进栈方法 if (top = maxsize - 1)/栈满返回栈满返回false return
7、 false; top+; datatop = e; return true; public bool Pop(ref T e)/元素出栈方法元素出栈方法 if (top = -1)/栈空返回栈空返回false return false; e = datatop; top-; return true; class Program static void Main(string args) /-整数栈操作整数栈操作-int e = 0; Stack s1 = new Stack(); /定义整数栈定义整数栈 s1.Push(1); /进栈进栈3个整数个整数 s1.Push(2); s1.Push
8、(3); Console.Write(整数栈出栈次序:整数栈出栈次序:); while (!s1.StackEmpty()/栈不空时出栈元素栈不空时出栈元素 s1.Pop(ref e); Console.Write(0 , e); Console.WriteLine(); /-实数栈操作实数栈操作- double d= 0; Stack s2 = new Stack();/定义实数栈定义实数栈 s2.Push(2.5);/进栈进栈3个实数个实数 s2.Push(3.8); s2.Push(5.9); Console.Write(实数栈出栈次序:实数栈出栈次序:); while (!s2.Sta
9、ckEmpty()/栈不空时出栈元素栈不空时出栈元素 s2.Pop(ref d); Console.Write(0 , d); Console.WriteLine(); /-学生对象栈操作学生对象栈操作- Student st =new Student(); Stack s3 = new Stack();/定义学生栈定义学生栈 s3.Push(new Student(1,Student1);/进栈进栈3个学生对象个学生对象 s3.Push(new Student(2,Student2); s3.Push(new Student(3,Student3); Console.Write(学生对象栈出
10、栈次序:学生对象栈出栈次序:); while (!s3.StackEmpty()/栈不空时出栈元素栈不空时出栈元素 s3.Pop(ref st); st.Dispstudent(); Console.WriteLine(); /-教师对象栈操作教师对象栈操作- Teacher te = new Teacher(); Stack s4 = new Stack();/定义教师栈定义教师栈 s4.Push(new Teacher(1, Teacher1); /进栈进栈3个教师对象个教师对象 s4.Push(new Teacher(2, Teacher2); s4.Push(new Teacher(3
11、, Teacher3); Console.Write(教师对象栈出栈次序:教师对象栈出栈次序:); while (!s4.StackEmpty()/栈不空时出栈元素栈不空时出栈元素 s4.Pop(ref te); te.Dispteacher(); Console.WriteLine(); 本程序先声明本程序先声明Student和和Teacher两个类,再声明一个两个类,再声明一个泛型栈泛型栈Stack,然后实例化为整数栈,然后实例化为整数栈s1、实数栈、实数栈s2、学、学生对象栈生对象栈s3和教师对象栈和教师对象栈s4,各自进栈,各自进栈3个元素后并出栈,个元素后并出栈,程序执行结果如图程序
12、执行结果如图7.2所示。所示。7.1.3 7.1.3 泛型的泛型的MSILMSIL代码分析代码分析 与与.NET Framework同时发布的中间语言反汇编工具同时发布的中间语言反汇编工具(ildasm.exe)可以加载任意的)可以加载任意的.NET程序集并分析它的内程序集并分析它的内容,包括关联的清单、容,包括关联的清单、MSIL代码和类型元数据。代码和类型元数据。 在命令行方式下进入在命令行方式下进入ildasm.exe所在的文件夹,键入所在的文件夹,键入ildasm命令,运行该程序,出现一个命令,运行该程序,出现一个“IL DASM”对话框,对话框,选择选择“文件文件|打开打开”命令。命
13、令。 选择例选择例7.1的程序的程序proj7-1.exe(位于(位于“D:C#程序程序ch7proj7-1proj7-1binDebug”文件夹中),便以树状图文件夹中),便以树状图展示该程序集的结构,展开所有项的结果如图展示该程序集的结构,展开所有项的结果如图7.3所示。所示。从例从例7.1程序的中间语言代码中可以看到如下要点。程序的中间语言代码中可以看到如下要点。1. 编译方式编译方式 第一轮编译时,编译器只为第一轮编译时,编译器只为Stack产生产生“泛型版泛型版”的的IL代码与元数据,并不进行泛型的实例化,代码与元数据,并不进行泛型的实例化,T在中间只在中间只充当占位符。例如,在充当
14、占位符。例如,在Stack的构造函数中占位符显示的构造函数中占位符显示为为。 在在JIT编译时,当编译时,当JIT编译器第一次遇到编译器第一次遇到Stack时,时,将用将用int替换替换“范型版范型版”IL代码与元数据中的代码与元数据中的T,即进行泛,即进行泛型类型的实例化。例如,型类型的实例化。例如,Main函数中显示的函数中显示的。2. 2. 引用类型作为参数和值类型作为参数引用类型作为参数和值类型作为参数 CLR为为所有类型参数为所有类型参数为“引用类型引用类型”的泛型类型产生的泛型类型产生同一份代码同一份代码;但是如果;但是如果类型参数为类型参数为“值类型值类型”,对每一个,对每一个不
15、同的不同的“值类型值类型”,CLR将为其产生一份独立的代码将为其产生一份独立的代码,这,这里的里的s3和和s4的的idloc.s的地址相同,都是的地址相同,都是CS$4$0000。 因为实例化一个引用类型的泛型,它在内存中分配的因为实例化一个引用类型的泛型,它在内存中分配的大小是一样的,但是当实例化一个值类型的时候,在内存大小是一样的,但是当实例化一个值类型的时候,在内存中分配的大小是不一样的。这样做的目的是尽可能减小代中分配的大小是不一样的。这样做的目的是尽可能减小代码量。码量。7.1.4 7.1.4 类型参数的约束类型参数的约束 在泛型类型或方法定义中,类型参数是在实例化泛型类在泛型类型或
16、方法定义中,类型参数是在实例化泛型类型的变量时指定的特定类型的占位符。型的变量时指定的特定类型的占位符。 那么,类型参数是不是任何类型呢?结论是否定的。那么,类型参数是不是任何类型呢?结论是否定的。例如,声明以下泛型类型:例如,声明以下泛型类型:class MyGTypestatic public bool LessThan(T1 obj1, T2 obj2) return obj1 obj2; 在编译时,系统指出在编译时,系统指出“运算符运算符无法应用于无法应用于T1和和T2类型类型的操作数的操作数”的错误。如果它是正确的,在实例化为的错误。如果它是正确的,在实例化为MyGType时,一个整
17、数和一个字符串怎么比较时,一个整数和一个字符串怎么比较呢?甚至在实例化为呢?甚至在实例化为MyGType时,一个整数时,一个整数和一个对象怎么比较呢?和一个对象怎么比较呢? 为了解决这个问题,为了解决这个问题,C#提出了类型参数的约束的概念。提出了类型参数的约束的概念。通过约束检查泛型列表中的某个项以确定它是否有效。通过约束检查泛型列表中的某个项以确定它是否有效。 例如,约束告诉编译器:仅此类型的对象或从此类型派生例如,约束告诉编译器:仅此类型的对象或从此类型派生的对象才可用作类型参数。一旦编译器有了这个保证,它就的对象才可用作类型参数。一旦编译器有了这个保证,它就能够允许在泛型类中调用该类型
18、的方法。能够允许在泛型类中调用该类型的方法。 约束是使用上下文关键字约束是使用上下文关键字 where 应用的。应用的。where子句的一子句的一般格式如下:般格式如下: where 类型参数:约束类型参数:约束1,约束,约束2, 例如,以下泛型有例如,以下泛型有3个类型参数,个类型参数,T1是未绑定的(没有是未绑定的(没有约束),约束),T2只有只有MyClass1类型或从它派生的类或类型或从它派生的类或MyClass2类型或从它派生的类才能用作类型实参,类型或从它派生的类才能用作类型实参,T3只有只有MyClass3类型或从它派生的类才能用作类型实参:类型或从它派生的类才能用作类型实参:c
19、lass MyClass where T2:MyClass1,MyClass2 T3:MyClass3 这样在对类型参数的类型种类施加限制后,如果使用这样在对类型参数的类型种类施加限制后,如果使用该泛型的代码尝试使用某个约束所不允许的类型来实例化该泛型的代码尝试使用某个约束所不允许的类型来实例化类,则会产生编译时错误。类,则会产生编译时错误。7.1.5 7.1.5 泛型的继承泛型的继承 C#除了可以单独声明泛型类型外,也可以在基类中除了可以单独声明泛型类型外,也可以在基类中包含泛型类型的声明。包含泛型类型的声明。 但基类如果是泛型类,它的类型要么已实例化,要但基类如果是泛型类,它的类型要么已实
20、例化,要么来源于子类(同样是泛型类型)声明的类型参数。么来源于子类(同样是泛型类型)声明的类型参数。例如,若声明了如下泛型:例如,若声明了如下泛型:class C则以下声明是正确的:则以下声明是正确的:class D:C/继承的类型已实例化继承的类型已实例化class E:C/E类型为类型为C类型提供了类型提供了U、V,即来源于子类,即来源于子类class F:C /F类型继承于类型继承于C,可看成,可看成F继继承一个非泛型的类承一个非泛型的类而以下声明是错误的:而以下声明是错误的:class G:C /因为因为G类型不是泛型,类型不是泛型,C是泛型,是泛型,G无法给无法给C提供泛提供泛型的实
21、例化型的实例化 7.1.6 7.1.6 泛型接口和委托泛型接口和委托1. 泛型接口泛型接口 与泛型继承类似,泛型接口的类型参数要么已实例化,与泛型继承类似,泛型接口的类型参数要么已实例化,要么来源于实现类声明的类型参数。要么来源于实现类声明的类型参数。 2. 泛型委托泛型委托 泛型委托支持在委托返回值和参数上应用参数类型,泛型委托支持在委托返回值和参数上应用参数类型,这些参数类型同样可以附带合法的约束。这些参数类型同样可以附带合法的约束。例如:例如:delegate bool MyDelegate(T value);class MyClass static bool method1(int i
22、) static bool method2(string s) static void Main() MyDelegate p2 = method2; MyDelegate p1 = new MyDelegate( method1); 反射是一种机制,通过这种机制可以知道一个未知类反射是一种机制,通过这种机制可以知道一个未知类型的类型信息。型的类型信息。例如有一个对象,它例如有一个对象,它不是我们定义的不是我们定义的,既可能是通过,既可能是通过网络捕捉到的,也可能是使用泛型定义的,但我们网络捕捉到的,也可能是使用泛型定义的,但我们想知道想知道这个对象的类型信息,想知道这个对象有哪些方法或者属这
23、个对象的类型信息,想知道这个对象有哪些方法或者属性什么性什么的,甚至的,甚至想进一步调用这个对象的方法想进一步调用这个对象的方法。关键是现。关键是现在只知道它是一个对象,不知道它的类型,自然不会知道在只知道它是一个对象,不知道它的类型,自然不会知道它有哪些方法等信息,这时该怎么办呢它有哪些方法等信息,这时该怎么办呢?7.2.1 7.2.1 反射概述反射概述反射机制就是解决这么一个问题的,通过反射机制就是解决这么一个问题的,通过反射机制就反射机制就可以知道未知类型对象的类型信息可以知道未知类型对象的类型信息。归纳归纳起来,反射在下列情况下很有用:起来,反射在下列情况下很有用:l 需要访问程序元数
24、据的属性。需要访问程序元数据的属性。l 检查和实例化程序集中的类型。检查和实例化程序集中的类型。l 在运行时构建新类型。在运行时构建新类型。l 执行后期绑定,访问在运行时创建的类型的方法。执行后期绑定,访问在运行时创建的类型的方法。1. Type类类System.Reflection是反射的命名空间,而是反射的命名空间,而Type类为类为System.Reflection功能的根,也是访问元数据的主要方式。功能的根,也是访问元数据的主要方式。Type类表示类型声明,包括类类型、接口类型、数组类表示类型声明,包括类类型、接口类型、数组类型、值类型、枚举类型、类型参数、泛型类型定义,以类型、值类型
25、、枚举类型、类型参数、泛型类型定义,以及开放或封闭构造的泛型类型。及开放或封闭构造的泛型类型。7.2.2 7.2.2 反射中常用的类反射中常用的类公共属性公共属性说明说明IsAbstract获取一个值,通过该值指示获取一个值,通过该值指示Type是否为抽象的并且必须被重写是否为抽象的并且必须被重写IsArray获取一个值,通过该值指示获取一个值,通过该值指示Type是否为数组是否为数组IsByRef获取一个值,通过该值指示获取一个值,通过该值指示Type是否由引用传递是否由引用传递IsClass获取一个值,通过该值指示获取一个值,通过该值指示Type是否是一个类,即不是值类型或接口是否是一个类
26、,即不是值类型或接口IsInterface获取一个值,通过该值指示获取一个值,通过该值指示Type是否为接口,即不是类或值类型是否为接口,即不是类或值类型IsSubclassOf确定当前确定当前Type表示的类是否是从指定的表示的类是否是从指定的Type表示的类派生的表示的类派生的MakeArrayType返回一个表示当前类型的一维数组(下限为零)的返回一个表示当前类型的一维数组(下限为零)的Type对象对象Module获取在其中定义当前获取在其中定义当前Type的模块的模块Name获取当前成员的名称获取当前成员的名称Namespace获取获取Type的命名空间的命名空间ReflectedTy
27、pe获取用于获取该成员的类对象获取用于获取该成员的类对象Type类的属性类的属性方法方法说明说明GetElementType当在派生类中重写时,返回当前数组、指针或引用类型包含的或引用当在派生类中重写时,返回当前数组、指针或引用类型包含的或引用的对象的的对象的TypeGetEvent获取由当前获取由当前Type声明或继承的特定事件声明或继承的特定事件GetEvents获取由当前获取由当前Type声明或继承的事件声明或继承的事件GetField获取当前获取当前Type的特定字段的特定字段GetFields获取当前获取当前Type的字段的字段GetInterface获取由当前获取由当前Type实现
28、或继承的特定接口实现或继承的特定接口GetInterfaces当在派生类中重写时,获取由当前当在派生类中重写时,获取由当前Type实现或继承的所有接口实现或继承的所有接口GetMember获取当前获取当前Type的指定成员的指定成员GetMembers获取当前获取当前Type的成员(包括属性、方法、字段、事件等)的成员(包括属性、方法、字段、事件等)GetMethod获取当前获取当前Type的特定方法的特定方法GetMethods获取当前获取当前Type的方法的方法GetProperties获取当前获取当前Type的属性的属性GetProperty获取当前获取当前Type的特定属性的特定属性I
29、nvokeMember使用指定的绑定约束并匹配指定的参数列表,调用指定成员使用指定的绑定约束并匹配指定的参数列表,调用指定成员Type类的方法类的方法归纳起来,得到一个归纳起来,得到一个Type实例的三种方法如下:实例的三种方法如下:(1)使用)使用System.Object.GetType(),例如:例如:Person pe=new Person();/定义定义pe为为person类的一个对象类的一个对象Type t=pe.GetType();这样这样t为为pe的的Type对象。对象。(2)使用)使用System.Type.GetType()静态方法,静态方法,参数为参数为类型的完全限定名。
30、例如:类型的完全限定名。例如:Type t=Type.GetType(MyNs.Person);其中,其中,MyNs.Person为为MyNs命名空间中的命名空间中的Person类,类,这样这样t为该类的为该类的Type对象。对象。(3)使用)使用typeof运算符运算符,例如:,例如:Type t=typeof(Person);其中其中Person为一个类,这样为一个类,这样t为该类的为该类的Type对象。对象。2. System.Reflection反射命名空间反射命名空间System.Reflection反射命名空间包含提供加载类型、方反射命名空间包含提供加载类型、方法和字段的有组织的视
31、图的类和接口,具有动态创建和调法和字段的有组织的视图的类和接口,具有动态创建和调用类型的功能。其中主要的类及其功能如下:用类型的功能。其中主要的类及其功能如下:l Assembly类:类:通过它可以加载、了解和操作一个程序集。通过它可以加载、了解和操作一个程序集。l AssemblyName类:类:通过它可以找到大量隐藏在程序集的身份通过它可以找到大量隐藏在程序集的身份中的信息,如版本信息、区域信息等。中的信息,如版本信息、区域信息等。l ConstructorInfo类:类:用于发现构造函数及调用构造函数。通用于发现构造函数及调用构造函数。通过对过对ConstructorInfo调用调用In
32、voke来创建对象,其中来创建对象,其中ConstructorInfo是由是由Type对象的对象的GetConstructors或或GetConstructor方法返回的。方法返回的。l EventInfo类:类:通过它可以找到事件的信息。通过它可以找到事件的信息。l FieldInfo类:类:通过它可以找到字段的信息。通过它可以找到字段的信息。l MethodInfo类:类:通过它可以找到方法的信息。通过它可以找到方法的信息。l ParameterInfo类:类:通过它可以找到参数的信息。通过它可以找到参数的信息。l PropertyInfo类:类:通过它可以找到属性的信息。通过它可以找到属
33、性的信息。l MemberInfo类:类:它是一个抽象基类,为它是一个抽象基类,为EventInfo、FieldInfo、MethodInfo、PropertyInfo等类型定义了公共的行为。等类型定义了公共的行为。l Module类:类:用来访问带有多文件程序集的给定模块。用来访问带有多文件程序集的给定模块。l DefaultMemberAttribute类:类:定义某类型的成员,该成员是定义某类型的成员,该成员是InvokeMember使用的默认成员。使用的默认成员。 公共属性公共属性说明说明EntryPoint获取此程序集的入口点获取此程序集的入口点FullName获取程序集的显示名称获
34、取程序集的显示名称Location获取包含清单的已加载文件的路径或位置获取包含清单的已加载文件的路径或位置ManifestModule获取包含当前程序集清单的模块获取包含当前程序集清单的模块其中其中重要的重要的Assembly类,它的常用属性和常用方法如下。类,它的常用属性和常用方法如下。Assembly类的常用属性类的常用属性 方法方法说明说明GetFiles获取程序集清单文件表中的文件获取程序集清单文件表中的文件GetModule获取此程序集中的指定模块获取此程序集中的指定模块GetModules获取作为此程序集的一部分的所有模块获取作为此程序集的一部分的所有模块GetType获取表示指定
35、类型的获取表示指定类型的Type对象对象GetTypes获取此程序集中定义的类型获取此程序集中定义的类型LoadFile加载程序集文件的内容加载程序集文件的内容LoadFrom在已知程序集的文件名或路径等信息时加载程序集在已知程序集的文件名或路径等信息时加载程序集LoadModule加载此程序集的内部模块加载此程序集的内部模块Assembly类的常用方法类的常用方法 1. 通过反射查看类型的成员信息通过反射查看类型的成员信息查看类型信息的过程如下:查看类型信息的过程如下:(1)获取指定类型的一个)获取指定类型的一个Type对象或对象或Type对象数组。对象数组。(2)通过)通过Type类的许多
36、方法来发现与该类型的成员有类的许多方法来发现与该类型的成员有关的信息。关的信息。7.2.3 7.2.3 反射的应用示例反射的应用示例【例例7.3】 编写一个程序,通过反射输出编写一个程序,通过反射输出System.Object类的方法、字段和构造函数的信息。类的方法、字段和构造函数的信息。解:解:先通过先通过Type的的GetTypes()方法获取方法获取System.Object类类的的Type对象对象t,然后用,然后用Type类的类的GetMethods()、GetFields()、GetConstructors()分别获取分别获取t对象的方法、字段和构造函数信对象的方法、字段和构造函数信
37、息并输出。程序如下:息并输出。程序如下:using System;using System.Reflection;namespace proj7_3class Programstatic void Main(string args) string classname = System.Object;Console.WriteLine(0类类,classname);Type t = Type.GetType(classname);MethodInfo m = t.GetMethods();Console.WriteLine( 0的方法个数的方法个数:1, t.FullName, m.Length
38、);foreach(MethodInfo item in m) Console.WriteLine(t0 ,item.Name); FieldInfo f = t.GetFields(); Console.WriteLine( 0的字段个数的字段个数:1, t.FullName, f.Length); foreach (FieldInfo item in f) Console.WriteLine(t0 , item.Name); ConstructorInfo c = t.GetConstructors();Console.WriteLine( 0的构造函数个数的构造函数个数:1, t.Ful
39、lName, c.Length);foreach (ConstructorInfo item in c)Console.WriteLine(t0 , item.Name); 程序执行结果程序执行结果2. 通过反射调用未知类的某方法通过反射调用未知类的某方法调用未知类的某方法的过程如下:调用未知类的某方法的过程如下:(1)假设一个未知类)假设一个未知类c属于某个属于某个DLL文件文件xyz.dll,采,采用用Assembly.LoadFrom(xyz.dll)加载该程序集。加载该程序集。(2)调用)调用assembly.GetTypes()方法得到一个方法得到一个Type对对象数组象数组t。(3
40、)通过)通过Type.GetConstructor()方法得到某个对象方法得到某个对象的构造函数。的构造函数。(4)通过)通过ConstructorInfo.Invoke()方法调用构造函方法调用构造函数创建未知类的对象数创建未知类的对象s。(5)通过对象)通过对象s调用某方法。调用某方法。【例例7.4】 有一个项目有一个项目proj7_4,通过添加代码文件模板,通过添加代码文件模板向其中添加一个向其中添加一个Sport.cs文件,该文件的内容如下:文件,该文件的内容如下: using System;public abstract class Sport/体育运动类体育运动类protected
41、 string name; /项目名项目名public abstract string GetDuration();/获取比赛时间获取比赛时间public abstract string GetName();/获取项目名获取项目名 在命令行方式下使用以下命令生成在命令行方式下使用以下命令生成Sport.dll文件:文件:csc/target:library Sport.cs同样通过添加代码文件模板向其中添加一个同样通过添加代码文件模板向其中添加一个SomeSports.cs文件,该文件的内容如下:文件,该文件的内容如下:using System;public class Basketball
42、: Sport public Basketball()/篮球类篮球类 name = 篮球篮球; public override string GetDuration() return 共共4节节,每,每节节15分钟分钟; public override string GetName() return name; public class Hockey : Sport/曲棍球类曲棍球类public Hockey()name = 曲棍球曲棍球; public override string GetDuration()return 两个半场,两个半场,各各35分钟分钟; public overrid
43、e string GetName()return name; public class Football : Sport/足球类足球类public Football()name = 足球足球; public override string GetDuration()return 两个半场,两个半场,各各45分钟分钟; public override string GetName()return name; 在命令行方式下使用以下命令生成在命令行方式下使用以下命令生成SomeSports.dll文件:文件:csc/target:library /reference:Sport.dll SomeSports.cs这样就生成两个动态链接库文件这样就生成两个动态链接库文件Sport.dll和和SomeSports.dll。现要在现要在Prog
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 日照市五莲县教体系统招聘专业教师考试真题2025
- 2026年小学二年级语文第二学期期末考试卷及答案(十八)
- 淀粉样变性心肌病精准诊疗
- 儿童噁唑烷酮类抗生素临床应用专家共识2026
- 三类人员继续教育培训班考试试卷
- 护理核心制度知识竞赛试题附答案(单选及多选)
- 2026毕业生c 面试题及答案
- 2026北影摄影面试题及答案
- 2025年中国琴式熨烫工作台市场调查研究报告
- 2025年中国牙科连锁管理系统市场调查研究报告
- 井冈山大学《经济地理学》2025-2026学年期末试卷
- 2026江苏苏州市健康养老产业发展集团有限公司下属子公司招聘15人(第二批)笔试参考试题及答案解析
- 2026贵州黔西南技师学院公开招聘事业单位工作人员14人考试备考试题及答案解析
- 心脏介入护理新进展与分享
- MOOC 跨文化交际通识通论-扬州大学 中国大学慕课答案
- (正式版)SHT 3078-2024 立式圆筒形料仓工程设计规范
- GB/T 23510-2009车用燃料甲醇
- 基层管理者的执行力培训课程
- 中等职业学校班主任能力比赛汽车运用与维修专业班级建设方案
- 静脉输液(教学)课件
- 山西恒泰佳源生物科技有限公司新建年产15万吨乙酸钠项目环评报告书
评论
0/150
提交评论