Free mag vol1 | Page 418

CHAPTER 9  COLLECTIONS AND GENERICS // must extend SomeBaseClass and have a default ctor, // while must be a structure and implement the // generic IComparable interface. public class MyGenericClass where K : SomeBaseClass, new() where T : struct, IComparable { ... } You will rarely encounter cases where you need to build a complete custom generic collection class; however, you can use the where keyword on generic methods, as well. For example, if you want to specify that your generic Swap() method can operate only on structures, you would update the method like this: // This method will swap any structure, but not classes. static void Swap(ref T a, ref T b) where T : struct { ... } Note that if you were to constrain the Swap() method in this manner, you would no longer be able to swap string objects (as is shown in the sample code) because string is a reference type. The Lack of Operator Constraints I want to make one more comment on generic methods and constraints as this chapter draws to a close. It might come as a surprise to you to find out that, when creating generic methods, you will get a compiler error if you apply any C# operators (+, -, *, ==, etc.) on the type parameters. For example, imagine the usefulness of a class that can Add(), Subtract(), Multiply(), and Divide() generic types: // Compiler error! Cannot apply // operators to type parameters! public class BasicMath { public T Add(T arg1, T arg2) { return arg1 + arg2; } public T Subtract(T arg1, T arg2) { return arg1 - arg2; } public T Multiply(T arg1, T arg2) { return arg1 * arg2; } public T Divide(T arg1, T arg2) { return arg1 / arg2; } } Unfortunately, the preceding BasicMath class will not compile. While this might seem like a major restriction, you need to remember that generics are generic. Of course, the numerical data can work just fine with the binary operators of C#. However, for the sake of argument, if were a custom class or structure type, the compiler could assume the class supports the +, -, *, and / operators. Ideally, C# would allow a generic type to be constrained by supported operators, as in this example: // Illustrative code only! public class BasicMath where T : operator +, operator -, operator *, operator / { 357