Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 122 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
122
Dung lượng
711,5 KB
Nội dung
Chapter Generics Hoang Anh Viet VietHA@it-hut.edu.vn HaNoi University of Technology Objectives “This chapter introduces you to probably the most exciting feature added to C# 2.0 and the CLR Those familiar with C++ templates will find generics somewhat familiar, though many fundamental differences exist Using generics, you can provide a shell of functionality within which to define more specific types at run time Generics are most useful with collection types and provide great efficiency compared to the collections used in previous NET versions ” Microsoft Microsoft Roadmap 9.1 Difference Betweet Generics and C++ Template 9.2 Efficency and Type Safety of Generics 9.3 Generic Type Definitions and Constructed Generics 9.4 Generic Classes and Structs 9.5 Generic Interfaces 9.6 Generic Method 9.7 Generic Delegates 9.8 Generic Type Conversion 9.9 Default Value Expression 9.10 Nullable Types Microsoft Microsoft Roadmap 9.11 Constructed Types Control Accessibility 9.12 Generic and Inheritance 9.13 Contraints 9.14 Contraints on Nonclass Types 9.15 Generic System Conllection 9.16Generic System Interfaces 9.17 Select Problems and Solutions 9.18 Conversion and Operations on Within Generic Types 9.19 Creating Constructed Types Dynamically Microsoft Microsoft 9.1 Difference Betweet Generics and C++ Template C++ Template • • • Microsoft Expansion of C++ templates is static C++ templates are always expanded at compile time Therefore, the C++ compiler must have access to all template types— generally through header files It is impossible to package C++ templates into libraries , because any types used to create the closed types from the template types at compile time That’s why all of the code for C++ template types usually lives in headers Microsoft 9.1 Difference Betweet Generics and C++ Template Generics • • • • • • Microsoft They can be packaged in assemblies and consumed later Constructed types are formed at run time instead of being form at compile time In many ways, this makes generics more flexible Generics significantly differently at design time than C++ templates The syntax for every other element in C# is based on the corresponding C++ syntax to leverage existing knowledge But the designers have streamlined the syntax and removed some of the verbosity Microsoft Roadmap 9.1 Difference Betweet Generics and C++ Template 9.2 Efficency and Type Safety of Generics 9.3 Generic Type Definitions and Constructed Generics 9.4 Generic Classes and Structs 9.5 Generic Interfaces 9.6 Generic Method 9.7 Generic Delegates 9.8 Generic Type Conversion 9.9 Default Value Expression 9.10 Nullable Types Microsoft Microsoft Efficency of Generics The added efficiency when using value types in collections is one of the greatest gains from generics in C# o The ArrayList maintains a collection of System.Object types o Any reference or value type that is added to an ArrayList is implicitly upcast to Object o If the items are value types, they must be boxed when they are added to the list, and unboxed when they are retrieved Both the casting and the boxing and unboxing operations decrease performance; Microsoft Microsoft Efficency of Generics Use generics to avoid the casting and the boxing and unboxing operations Example List list1 = new List(); // No boxing, no casting: list1.Add(3); Microsoft Microsoft Efficency of Generics Use generics to create many kinds of class(interface, ) from a generic class(interface, ) instead of using many classes(interfaces, ) which have the same form public void SomeMethod(long x ) { public long t; t= x*x; Console.WriteLine(“Squere of x is : {1}”,t); } public void SomeMethod(int x ) { public int t; t= x*x; Console.WriteLine(“Squere of x is : {1}”,t); } //Use generic SomeMethod public void SomeMethod(T x) { public T t; t= x*x; Console.WriteLine(“Squere of x is : {1}”,t); } //Call the SomeMethod(long x): SomeMethod(x); //Call the SomeMethod(int x) SomeMethod(x) Microsoft Microsoft 10 Roadmap 9.11 Constructed Types Control Accessibility 9.12 Generic and Inheritance 9.13 Contraints 9.14 Contraints on Nonclass Types 9.15 Generic System Conllection 9.16Generic System Interfaces 9.17 Select Problems and Solutions 9.18 Conversion and Operations on Within Generic Types 9.19 Creating Constructed Types Dynamically Microsoft Microsoft 108 9.18 Conversion and Operators Within Generic Types Converting from one type to another or applying operators to parameterized types within generics can prove to be tricky To illustrate, let’s develop a generic Complex struct that represents a complex number You could start out by defining the Complex number as follows Microsoft Microsoft 109 Conversion and Operators Within Generic Types using System; public struct Complex where T : struct { public Complex(T real, T imaginary) { this.real = real; this.imaginary = imaginary; } public T Real { get { return real; } set { real = value; } } public T Img { get { return imaginary; } set { imaginary = value; } } private T real; private T imaginary; } public class EntryPoint { static void Main() { Complex c = new Complex(4, 5); } } Microsoft Operators: Get,Set with generic type Microsoft 110 Conversion and Operators Within Generic Types Now let’s make this value type a little more useful by having a Magnitude property that returns the square root of the two components multiplied together public struct Complex where T: struct { public T Magnitude { get { // WON'T COMPILE!!! return Math.Sqrt( real * real + maginary * imaginary ); } } Microsoft Microsoft 111 public class EntryPoint { static void Main() { Complex c = new Complex( 3, ); Console.WriteLine( "Magnitude is {0}", c.Magnitude ); } } Microsoft Microsoft 112 Conversion and Operators Within Generic Types If you attempt to compile this code, you may be surprised to get the following compiler error: error CS0019: Operator '*' cannot be applied to operands of type 'T' and 'T' This is a perfect example of the problem with using operators in generic code A common technique is to externalize the operation from the Complex definition itself and then require the user of Complex to provide the operation A delegate is the perfect tool for doing this Microsoft Microsoft 113 public struct Complex where T: struct, IConvertible { public delegate T BinaryOp( T val1, T val2 ); public Complex( T real, T imaginary, BinaryOp mult, BinaryOp add, Converter convToT ) { Delegate for this.real = real; doing this.imaginary = imaginary; multiplication this.mult = mult; this.add = add; this.convToT = convToT; } public T Real { get { return real; } set { real = value; } } 114 public T Img { get { return imaginary; } set { imaginary = value; } } public T Magnitude { get { double magnitude = Math.Sqrt( Convert.ToDouble(add(mult(real, real), mult(imaginary, imaginary))) ); return convToT( magnitude ); } } private T real; private T imaginary; private BinaryOp mult; private BinaryOp add; private Converter convToT; }//end of struct Complex 115 public class EntryPoint { static void Main() { Complex c = new Complex( 3, 4, EntryPoint.MultiplyInt64, EntryPoint.AddInt64, EntryPoint.DoubleToInt64); Console.WriteLine("Magnitude is {0}", c.Magnitude); } static Int64 MultiplyInt64(Int64 val1, Int64 val2) { return val1 * val2; } static Int64 AddInt64(Int64 val1, Int64 val2) { return val1 + val2; } static Int64 DoubleToInt64(double d) { return Convert.ToInt64(d); } } 116 Roadmap 9.11 Constructed Types Control Accessibility 9.12 Generic and Inheritance 9.13 Contraints 9.14 Contraints on Nonclass Types 9.15 Generic System Conllection 9.16Generic System Interfaces 9.17 Select Problems and Solutions 9.18 Conversion and Operations on Within Generic Types 9.19 Creating Constructed Types Dynamically Microsoft Microsoft 117 9.19 Creating Constructed Types Dynamically At run time, we can: • generate classes and code at run time • construct closed types from generics This functionality stems from a natural extension of the metadata specification to accommodate generics The type System.Type is the cornerstone of functionality whenever you need to work with types dynamically Some of the new methods on System.Type, such as GetGenericArguments, GetGenericParameterConstraints, and GetGenericTypeDefinition are helpful when we already have a System.Type instance representing a closed type Microsoft Microsoft 118 9.19 Creating Constructed Types Dynamically For example, creating a parsing engine for some sort of XML-based language that defines new types from generics is a snap Let’s take a look at an example of how you use the MakeGenericType method: Microsoft Microsoft 119 Example public class EntryPoint { static void Main() { IList intList = (IList)CreateClosedType(typeof(List)); IList doubleList = (IList) CreateClosedType(typeof(List)); Console.WriteLine(intList); Console.WriteLine(doubleList); } static object CreateClosedType(Type genericType) { Type[] typeArguments = { typeof( T ) }; Type closedType = genericType.MakeGenericType(typeArguments); return Activator.CreateInstance(closedType); } } 120 9.19 Creating Constructed Types Dynamically The meat of this code is inside the generic method CreateClosedType All of the work is done in general terms via references to Type created from the available metadata First, you need to get a reference to the generic, open type List After that, you simply create an array of Type instances to pass to MakeGenericType to obtain a reference to the closed type The ability to create closed types at run time is yet another powerful tool in your toolbox for creating highly dynamic systems Microsoft Microsoft Sumary In this chapter, we have learn: • How to declare and use generics using C#, including generic • • • Microsoft classes,structs, interfaces, methods, and delegates We also discussed generic constraints Collection types gain a real and measurable gain in efficiency and safety with generics Create much more power when enforcing type safety Microsoft 122 ... Betweet Generics and C++ Template 9.2 Efficency and Type Safety of Generics 9.3 Generic Type Definitions and Constructed Generics 9.4 Generic Classes and Structs 9.5 Generic Interfaces 9.6 Generic. .. Betweet Generics and C++ Template 9.2 Efficency and Type Safety of Generics 9.3 Generic Type Definitions and Constructed Generics 9.4 Generic Classes and Structs 9.5 Generic Interfaces 9.6 Generic. .. Betweet Generics and C++ Template 9.2 Efficency and Type Safety of Generics 9.3 Generic Type Definitions and Constructed Generics 9.4 Generic Classes and Structs 9.5 Generic Interfaces 9.6 Generic