![]() |
|
Spaces home DevelopmentalProfileFriendsBlogMore ![]() | ![]() |
DevelopmentalFlinging crap at other monkeys in the development forest
|
August 29 DEVSTA - The programming competition for star developers!Although it hasn't been officially announced by Microsoft yet, the information was revealed on the OzSilverLight mailing list today that there will be a programming competition for Australian developers starting in September. Here is the URL: http://devsta.microsoft.com.au/ What's really interesting about this particular competition is that it is offering some seriously cool prizes! For instance, first place is an all expenses paid trip to Mix09 in Vegas next year, an XBOX Elite plus games, and a MSDN subscription. The "theme" of the competition will be announced on 29th September, and then it will be open slather. Developers will have exactly 200 hours and 8 minutes to complete their submission for the competition. So start stocking that jolt cola and be ready on 29th Sept to compete to become the next DEVSTA! August 20 System.IConvertible - Its not a FerrariYou might be familiar with the System.Convert class, which has a number of methods for converting from/to different types. For example:
We live in a world of casting and you might find this code somewhat pointless. After all, it will still raise StackOverflowException and lose precision with floating poing conversions, so what's the point? The convert class is capable of converting an instance of ANY type into one of the common base types (sting, int, ulong, char, etc). If a type implements the System.IConvertible interface, it can define how conversions of that type will occur. Lets consider a (not so practical) example. Say we have a product class with the following properties:
Our Product class also has a parameterless constructor. In this example, we also make the Product class implement the IConvertible interface. This forces us to implement 16 methods and 1 property. Those methods all relate directly to conversion. For example, here's the implementation of one of those methods:
What we are saying here is that if someone tries to convert our Product instance to a ulong then it will simply assign the ProductId. Our test code looks like this:
The output is the number "7" because that is how our implementation of IConvertible tells the Convert class to handle conversions to UInt64. Simple eh?
July 01 Rolling back a changeset in TFSIn TFS 2005 and 2008 there is no easy way of rolling back a changeset. Sure, you can do a "get specific version" of each file from before the "bad" checkin occurred, and then check the older version back in. But this really sucks if you have a lot of files in your changeset. Luckily the Team Foundation Power Tools can help you here. One of the command line options is as follows:
Here, you simply replace xxxx with your changeset number, and the power tools will take care of the rest. First, it will "get latest" of the workspace. Next it will perform an operation for each file that is required to roll it back. For example, if you added a file, it performs a delete. If you deleted a file, it performs an undelete. If you simply edited a file, it will get the code from the changeset previous for that file. The result on the command line indicates which changeset was used for each file it rolled back. It then pops up a window requesting confirmation for all the files. After this, it checks out all those files it will roll back and you can then check them in (or only check some in if you so wish). One caveat with this process is that when you are executing the command line, you might get an error: "Unable to determine workspace". This simply means you are not currently in a folder that is part of a workspace. Change directory into a folder that is stored in the workspace you want to use (for those that use multiple workspaces with different folders). Good news is that Rosario will have rollback features incorporated. Check out the help for rollback for more information:
June 13 Destroy Work Item : Is it really gone?This week we had a situation where we needed to remove a work item from the TFS database completely. You can delete a work item in Team Explorer however this just marks the row in the database as deleted and as such your database will always grow, never shrink. The Visual Studio Team System 2008 Team Foundation Power Tools give us the ability to destroy a work item with the 'destroyWI' call. Here's the command line syntax:
The 'intention' is to delete all instances of the ID from the database, and all related data, and in truth it comes pretty close. However there is one table it misses: 'WorkItemsWere' If you look at your TFS database instance you will notice there are actually a few databases. One of them is 'WorkItemTracking' and this database contains all the tables related to work items. The astute might also notice that each of the databases in their instance seems to match each of the web services provided by TFS. Coincidence? In the 'WorkItemTracking' database you will see a number of tables that all contain work item related data. In particular, notice the two tables: 'WorkItemsAre' and 'WorkItemsWere'. The 'Are' table contains the current state of a work item while the 'Were' table contains its history. For example, work item 1234 is modified several times. First it is opened as a bug and assigned to 'triage'. Then triage moves it to the developer who fixes the bug and resolves it with comments, where it is assigned back to the user who opened it. The bug isn't fixed, some additional comments are inserted, its assigned back to the developer, and so on. If you are familiar with work items, you will be able to identify the 'History' section where you can view the audit history. This essentially is what is stored in the 'WorkItemsWere' table. Makes sense now right? Yesterday I did a destroy of a work item and discovered that all the various tables had all instances cleaned up, except the 'WorkItemsWere' table. I contacted the VSTS team who indicated that this is indeed a bug and it is now logged in their own work item system (oh the irony!). What to do in the mean time? Well they assure me it is safe to delete the orphaned database rows, despite the general consensus on the net not to mess with the database directly. I can confirm however that this is the only table with orphaned data. And I'm sure this will be fixed up in a future release of the power tools. All round I quite like the TFPT and haven't even bothered with the multitude of 3rd party components that put a UI in front of it: real men use command line! June 01 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.
|
|
||||||||||||||||||||||||
|
|