I enjoyed the annotations in
The .NET Framework Standard Library Annotated Reference so much that I read
them all in one sitting (in the bathtub, if you must know…). The annotations
are where the authors put in their 2 cents about a particular class, method or
property and it was very interesting. Here’s what I learned just from that part
of the book:
You shouldn’t use ApplicationException for custom
exceptions. Derive from Exception instead.
Because
ICloneable.Clone doesn’t define whether it returns a deep or a shallow copy,
it’s practically worthless.
Prefer UTF-8 because it takes
up the same amount of space to represent ASCII characters as ASCII, but can
also represent all Unicode characters (I knew that UTF-8 took up the same
amount of space but hadn’t yet jumped to “prefer”).
I was
reminded of the System.Convert class, which does all of the same conversions
that the various type-specific ToXxx and Parse methods do, but puts them all
in one place.
There’s another use for the private
interface method implementation syntax in C#:
class Enum : IEnumerator {
object IEnumerator.Current { get { return this.foo; } }
...
}
This syntax hides an interface method from general use unless you
cast to the interface base class:
Enum enum = new Enum(); object obj1 = enum.Current(); // compile-time error object obj2 = (IEnumerator)enum.Current(); // this works
The thing I never thought of that this enables is that it lets you override
based on return type, which isn’t normally allowed in C#:
class Enum : IEnumerator {
object IEnumerator.Current { get { return this.foo; } Foo Current { get { return this.foo; } }
...
}
This private method implementation syntax lets you return the
generic type as part of the interface implementation so that you can plug
into standard idioms, e.g. foreach, but a more specific type for users of
the type directly, saving the cast:
Enum enum2 = new Enum(); Foo foo1 = (Foo)((IEnumerator)enum.Current()); Foo foo2 = enum.Current(); // no cast required
This will be less interesting as generics take over, but still, it’s a
useful trick.
DateTime is always assumed to represent
local time, so if you convert to Universal time twice, you’ll change the
value each time.
Since it’s possible to cast any number to
an enum value, e.g. TrueFalseEnum tfe = (TrueFalseEnum)42, make sure to
always check that an enum is a legal value. Theoretically this is a pain,
but in practice, I tend to check enum values with switch statements, making
the default case the error case, so it’s good to know that my code does the
right thing.
The Threading.Interlocked class.
Jim Miller has way more birthdays than we do. : )
Jeff Richter agrees with me that the ThreadStart delegate needs an object
parameter.
I should be using CompareInfo instead of
ToLower for case-insensitive comparisons (although they don’t show how):
using System.Globalization;
using System.Threading;
... CompareInfo compare = Thread.CurrentThread.CurrentCulture.CompareInfo; if( compare.Compare("foo", "FOO", CompareOptions.IgnoreCase) == 0 ) { Console.WriteLine("the same");
}
If I can get that much out of just the annotations, imagine
what I could learn if I
read the whole thing. : )
Jason Olson, an enterprising 3rd party, posts a look at the benefits of knowing about threading when building an entire UI stack from scratch. Instead of requiring you to transition from a worker thread to the UI thread to talk to a control, Avalon lets you grab the UI context that owns the control and party on:
void ShowProgress(int secondsElapsed) {
try {
this.Context.Enter();
txtSeconds.Text = secondsElapsed.ToString();
}
finally {
this.Context.Exit();
}
}
This is far simpler code than what would be required in code based on User32. Nice.
There seems to be a common misconception that since Avalon windows/pages are/can be declared in markup (XAML), it must be a web killer/reach solution. It’s not.
In this short video, Joe Beda, answers the question of whether Avalon is meant to replace HTML/the web (it’s not) and what’s Avalon’s message of “best of the web/best of Windows” message is really about, e.g. ease of deployment for Avalon apps like web apps, accessing central services for data and functionality (using web services instead of client UI generation), etc.
In his June ’03 Bugslayer column, John Robbins made a sideways comment when discussing Son of Strike (SOS), a debugging extension from Microsoft for doing all kinds of low-level, mixed native and managed code debugging.
What Jon said was this: “Interestingly, starting with Visual Studio® .NET 2003, you can load SOS when doing mixed-mode debugging.” And then he didn’t say how to load SOS into VS.NET, even after spending the rest of the article telling us how cool SOS was.
Luckily, Mike Stanton, an SDE on the CLR team, has created a set of instructions for loading SOS into VS.NET. Actually, he posted those instructions in December of last year, but it wasn’t ’til today that they were accurate because it wasn’t ’til today that I tried them and couldn’t get them to work. Now they are and I can and I have all kinds of low-level goodness to explore with Son of Strike.
I gave a talk at the Twin Cities .NET User Group in Minneapolis in January and I met a guy there building a web sit to crawl .NET source code on the web. I didn't get his contact info and he didn't email me, so I don't know how to get a hold of him. If that's you, please drop me a line. Thanks!