Free mag vol1 | Page 416

CHAPTER 9  COLLECTIONS AND GENERICS } Console.ReadLine(); Here is the output: ***** Fun with Generic Structures ***** p.ToString()=[10, 10] p.ToString()=[0, 0] p2.ToString()=[5.4, 3.3] p2.ToString()=[0, 0]  Source Code You can find the GenericPoint project under the Chapter 9 subdirectory. Constraining Type Parameters As this chapter illustrates, any generic item has at least one type parameter that you need to specify at the time you interact with the generic type or member. This alone allows you to build some type-safe code; however, the .NET platform allows you to use the where keyword to get extremely specific about what a given type parameter must look like. Using this keyword, you can add a set of constraints to a given type parameter, which the C# compiler will check at compile time. Specifically, you can constrain a type parameter as described in Table 9-8. Table 9-8. Possible Constraints for Generic Type Parameters Generic Constraint Meaning in Life where T : struct The type parameter must ha ve System.ValueType in its chain of inheritance (i.e., must be a structure). where T : class The type parameter must not have System.ValueType in its chain of inheritance (i.e., must be a reference type). where T : new() The type parameter must have a default constructor. This is helpful if your generic type must create an instance of the type parameter because you cannot assume you know the format of custom constructors. Note that this constraint must be listed last on a multiconstrained type. where T : NameOfBaseClass The type parameter must be derived from the class specified by NameOfBaseClass. 355