13.07.2015 Views

C# in Depth

C# in Depth

C# in Depth

SHOW MORE
SHOW LESS
  • No tags were found...

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Beyond the basics79comb<strong>in</strong>ed together. Obviously no type can be both a reference type and a value type, sothat comb<strong>in</strong>ation is forbidden, and as every value type has a parameterless constructor,specify<strong>in</strong>g the construction constra<strong>in</strong>t when you’ve already got a value type constra<strong>in</strong>tis also not allowed (but you can still use new T() with<strong>in</strong> methods if T is constra<strong>in</strong>ed tobe a value type). Different type parameters can have different constra<strong>in</strong>ts, and they’reeach <strong>in</strong>troduced with a separate where.Let’s see some valid and <strong>in</strong>valid examples:Valid:class Sample where T : class, Stream, new()class Sample where T : struct, IDisposableclass Sample where T : class where U : struct, Tclass Sample where T : Stream where U : IDisposableInvalid:class Sample where T : class, structclass Sample where T : Stream, classclass Sample where T : new(), Streamclass Sample where T : struct where U : class, Tclass Sample where T : Stream, U : IDisposableI <strong>in</strong>cluded the last example on each list because it’s so easy to try the <strong>in</strong>valid one<strong>in</strong>stead of the valid version, and the compiler error is not at all helpful. Just rememberthat each list of type parameter constra<strong>in</strong>ts needs its own <strong>in</strong>troductory where. Thethird valid example is <strong>in</strong>terest<strong>in</strong>g—if U is a value type, how can it derive from T, whichis a reference type? The answer is that T could be object or an <strong>in</strong>terface that U implements.It’s a pretty nasty constra<strong>in</strong>t, though.Now that you’ve got all the knowledge you need to read generic type declarations,let’s look at the type argument <strong>in</strong>ference that I mentioned earlier. In list<strong>in</strong>g 3.2 weexplicitly stated the type arguments to List.ConvertAll—but let’s now ask the compilerto work them out when it can, mak<strong>in</strong>g it simpler to call generic methods.3.3.2 Type <strong>in</strong>ference for type arguments of generic methodsSpecify<strong>in</strong>g type arguments when you’re call<strong>in</strong>g a generic method can often seempretty redundant. Usually it’s obvious what the type arguments should be, based onthe method arguments themselves. To make life easier, the <strong>C#</strong> 2 compiler is allowed tobe smart <strong>in</strong> tightly def<strong>in</strong>ed ways, so you can call the method without explicitly stat<strong>in</strong>gthe type arguments.Before we go any further, I should stress that this is only true for generic methods. Itdoesn’t apply to generic types. Now that we’ve got that cleared up, let’s look at the relevantl<strong>in</strong>es from list<strong>in</strong>g 3.3, and see how th<strong>in</strong>gs can be simplified. Here are the l<strong>in</strong>esdeclar<strong>in</strong>g and <strong>in</strong>vok<strong>in</strong>g the method:static List MakeList (T first, T second)...List list = MakeList ("L<strong>in</strong>e 1", "L<strong>in</strong>e 2");Now look at the arguments we’ve specified—they’re both str<strong>in</strong>gs. Each of the parameters<strong>in</strong> the method is declared to be of type T. Even if we hadn’t got the partLicensed to Rhona Hadida

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!