Since the ADO.NET
Tips and Tricks blog entry seemed to generate some interest, I thought I'd post
a few more general .NET tips and tricks.
Lots of people know about the basic QuickStart
samples included with the .NET Framework SDK, but did you know that we also ship
some low-level source samples, including a basic LISP compiler and a code profiler
in the SDK? They're included in the Tool Developers Guide subdirectory (on my machine
this is at
\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Tool Developers). Also here are the full CLI specifications, including a reference describing
MSIL (the intermediate language into which .NET code is initially compiled).
Have you ever wondered where assemblies installed into the GAC are
physically stored? You'll be able to see them if you navigate to
Explorer, where you'll see a nicely formatted list of assemblies. The shell extension
responsible for this view shows not just assemblies in the GAC, but also the native
versions of assemblies pre-compiled with ngen.exe.
But the files aren't actually stored here - the shell extension simply masks their
true location. You can see where the files are really stored by navigating to the
same directory via a command prompt. In this location are a number of subdirectories,
including one named GAC. Buried here under several layers of hash codes and assembly
names resides the physical assemblies, along with an old-fashioned .INI file that
contains the strong name amongst other things. It's worth exploring in this uncharted
territory just to understand what's going on under the covers, although beware of
making changes as the GAC is intended to be opaque.
One of the best development utilities you can load on your machine is Lutz
Roeder's .NET Reflector (for
free!). No matter how much good documentation Microsoft were able to provide, nothing
beats looking at source code if you want to see what's really going on, and .NET Reflector
allows you to do exactly that. This tool allows you to both disassemble and decompile
.NET assemblies to see how they are constructed, and allows you to view the results
as both Visual Basic and C#. A positive side-effect of this is that it can help you
if you need to port from one language to another. Simply use this tool and then fix
up the local variables for their true names (locals are not stored as part of the
metadata of an application). I'm not going to get into a discussion about the merits
of code obfuscation - I'll simply point you to this
The first time you browse to an updated ASP.NET website, there's always a couple of
seconds pause whilst the ASP.NET worker process does something. But why should there
be a wait when you've just built the web application into an assembly using VS.NET?
The reason is quite surprising: ASP.NET applications using the code-behind model actually
comprise two separate assemblies at runtime. Rather than interpreting the
.aspx page, ASP.NET creates a class that dynamically spits out the HTML content when
instantiated. This class inherits from the class created in code-behind view, so that
both are linked together. The pause when you first browse to the site is caused by
this class being generated, compiled and instantiated. On subsequent visits to this
page, the class is already compiled (and probably also JITted), so the only step left
is to instantiate it. That's why repeated visits to a page are so much faster than
the initial visit. (In production this is rarely a problem, since web sites are of
course long lived and used by many users.) If you want to see the class that's automatically
generated, you can visit a directory called Temporary ASP.NET Files (on my machine
\WINDOWS\Microsoft.NET\Framework\v1.1.4322\Temporary ASP.NET Files).
Buried in here, you'll see an XML file for each page in the site, which contains the
name of the automatically generated C# or VB class that implements the dynamic HTML
rendering. As with tip #2, this location is deliberately obfuscated to prevent casual
tampering, but it's worth looking here just to see what's going on under the covers.
My favourite tool in Visual Studio .NET is the command window (press Ctrl+Alt+A to
open it). It opens up a whole new level of power when you're building applications.
You can use it both as an interactive debug window (for commands like
or in a command mode both at design-time and run-time. Command mode allows you to
execute a command like callstack (to view the call stack), access any of the menu
options directly, create aliases (for example, I've created an alias called
displays the contents of the GAC in the output window with
alias gac shell /output).
c:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin\gacutil.exe -lr