| Profilo di StevenDevelopmentalBlogElenchi | Guida |
|
01 giugno Advanced GenericsI've recently been reading this book by Jon Skeet about C# 2 and 3, and it got me all inspired to write about generics. Jon's great; he's extremely active in the C# and Java community, and recently responded to an email question I had in less than 10 minutes! I'm finding the book insightful and useful and greatly enjoying my bus rides to work when I get to read it. This post is going to assume you are familiar with using generic classes like List<T> and Nullable<T>. So lets start with the syntax for declaring our own generic class:
This is pretty simple: the Animator class accepts a generic type T and requires you pass a T in its constructor. The MoveOnce() method is empty at the moment, we'll get to that later.
Great! We've decided that the fact a Monkey can move and stop is pretty general, and is probably something other animals can do, so we've declared an interface to indicate our monkey has those capabilities. We might also define IEater, or IDungFlinger. Now we can revisit our generic type in our Animator class definition as follows:
This is where the magic begins. We've placed a constraint on our generic type, stating that it will only ever accept a type that implements our IMoveable interface. If we try to use the Animator class with something else, we will get a compile-time exception. Even better yet is that our development environment knows that since our instance will always implement IMoveable, it therefore must have a Move() and Stop() method, therefore we can call it anywhere in our class; in this case the MoveOnce() method. You can declare more than one generic type in your class definitions. Imaging a class that facilitates a race for monkeys, whether they be chimps, gorillas, or marmosets. Consider this generic class declaration:
Here we have defined that our class accepts 2 generic types: T and U. We have further restricted them that they both have to inherit from the Monkey class. Here's some example calls using this new class:
As you can see that anything that inherits Monkey is valid. Of interest, the second example shows that even an instance of Monkey is valid. This shows that the where clause in our type restriction means anything that inherits from X or is X. Finally here are a couple of extra cool things you can do with generic type restrictions as general non-monkey related examples:
TestCase1 demonstrates that we can force the type to be a reference type. TestCase3 shows that we can ensure T implements multiple interfaces.
This is valid because Chimp inherits from Monkey. The last TestCase7 is somewhat interesting. Its declaration indicates that T is a reference type, and U is a value type that must inherit from T. How can this be? It essentially states that you must pass a struct that inherits from a class. But C# won't let you declare this. To be honest at first I didn't know the answer to this. Thus the email to Jon, and his explanation was simple and it made sense: interfaces are reference types. Hopefully you are aware that structs can implement interfaces also (but can't do inheritance), so we might define a new animal as follows:
Then we can legitimately use the TestCase7 syntax:
Then of course, valid values for an IMoveable are a Chimp, Marmoset, or even another Mouse, while of course you can only use a Mouse for the second type. Hopefully this has given you a better idea of what you can do with generics. CommentiPer aggiungere un commento, accedi con il tuo Windows Live ID (se utilizzi Hotmail, Messenger o Xbox LIVE possiedi già un Windows Live ID). Accedi Non hai ancora un Windows Live ID? Registrati RiferimentiL'URL di riferimento per questo intervento è: http://stevennagy.spaces.live.com/blog/cns!B2EFDBF0964586B3!232.trak Blog che fanno riferimento a questo intervento
|
|
|