1. Stupid .NET Tricks #7

    September 27, 2007 by Craig

    The people who dreamed up the .NET API (most particularly the graphics APIs) and their documentation often make my mind boggle.

    For instance, what would you think if someone said to you: “You have 5 different options. Four of these are exactly the same. The other one is sometimes the same and sometimes not (though we can’t say when or why), and you’re not allowed to choose it some of the time.”

    That’s exactly what the official documentation for System.Drawing.Pen.Alignment states:

    This property determines how the Pen draws closed curves and polygons. The PenAlignment enumeration specifies five values; however, only two values—Center and Inset—will change the appearance of a drawn line. Center is the default value for this property and specifies that the width of the pen is centered on the outline of the curve or polygon. A value of Inset for this property specifies that the width of the pen is inside the outline of the curve or polygon. The other three values, Right, Left, and Outset, will result in a pen that is centered.

    A Pen that has its alignment set to Inset will yield unreliable results, sometimes drawing in the inset position and sometimes in the centered position. Also, an inset pen cannot be used to draw compound lines and cannot draw dashed lines with Triangle dash caps.

    I’m not sure which is worse: documentation that explains the stupidity of an API, or documentation that doesn’t explain the API at all:

    System.Windows.FormsControl.IsMirrored Property
    Gets a value indicating whether the control is mirrored.
    Property Value: true if the control is mirrored; otherwise, false

    (That’s all it says. There’s zero description of what “mirrored” actually means.)

    These two examples are particularly bad, but the entire .NET API is filled with similar deficiencies in both documentation and design. Java’s standard libraries, while not perfect, are on the whole much, much better. If it weren’t too late already, the entire .NET team should be beaten over the head with a copy of Elliot Rusty Harold’s XOM Design Principles and then locked in a room until they cleaned up their mess. What they produced was simply amateurish.


  2. Stupid .NET Trick #6

    September 26, 2007 by Craig

    As far as I can tell, you can’t handle key-repeating (ie: holding down a key for more than a brief period of time) in .NET without doing it manually through an obscene combination of KeyDown, KeyUp, and Timer. Google certainly doesn’t know how.

    Update:After reading this blog I figured it out. There’s two gotchas involved:

    1. Multiple KeyDown (and presumably KeyUp and KeyPress) events are in fact fired when you hold the key down, even though this isn’t mentioned in the documentation.
    2. KeyDown isn’t fired at all for the arrow keys (even though KeyUp appears to be, at least in the code I had at one point) unless you convert the arrow key into an “Input Key”, via either PreviewKeyDown or IsInputKey. Since I was concerned with the arrow keys I happened to not realize the above point in testing.

    Though it works, and in retrospect is quite easy to implement, it’s obscure enough that I’m not de-classifying this as a Stupid Trick.


  3. Moderately Clever .NET Trick #1

    September 22, 2007 by Craig

    System.Nullable is an autoboxing wrapper that brings support for null values to types that normally don’t support null (like int). Not allowing nulls for value types in the first place is a bit of a pest (although I won’t elevate it to the level of “Stupid .NET Trick”, as I think there’s at least some legitimate reasoning behind it). System.Nullable is a hack to work around that but it’s relatively clean: You can use the wrapper class directly, or you can simply suffix your variable with a “?” (thus you get “int? x = null”, which nicely indicates that the variable is not your standard int).


  4. Stupid .NET Tricks #5

    September 12, 2007 by Craig

    Java has three major types of collections:

    • Lists: a collection of values with a precise (ie: user-defined) order. Duplicate values are allowed (which makes the List a Bag). You can access each element by an numeric index.
    • Sets: a collection of values without a user-defined order. Duplicates are not allowed.
    • Map: a collection of key-value pairs (ie: a mapping of keys to values).

    These are then broken down into implementation-specific subtypes, each of which has applicable uses depending on the situation:

    • Hash: Useful when very quick (O(1)) retrieval access is desired, iteration over the entire collection is rare, and sort order is unimportant. Ex: HashMap, HashSet. Hash doesn’t conceptually agree with the user-ordering or duplicates of a List so there is no HashList (HashSet is usually sufficient)
    • Tree: Useful when quick (O(log n)) element access is desired, iteration over the entire collection is somewhat common, and sort order is important. Ex: TreeMap, TreeSet. Tree doesn’t conceptually agree with the user-ordering or duplicates of a List so there is no TreeList (TreeSet is usually sufficient)
    • Array: Useful when you desire a List/Bag collection, especially if the approximate number of elements is known beforehand. Provides very quick (O(1)) retrieval if you know the element’s index (which can be very common in some circumstances). Ex: ArrayList. You could, in theory, make an ArraySet and ArrayMap, but they’d end up performing worse than HashSet/HashMap and wouldn’t provide much additional functionality, so they’re not implemented in the standard Java packages.
    • Linked: Useful when the number of elements is not known beforehand (although ArrayList will still perform better in many cases). Ex: LinkedList. There’s also a LinkedHashSet which combines the features of a HashSet and a theoretical LinkedSet (which would be a very poor performer). Unfortunately there’s no LinkedHashMap in standard Java. LinkedList works well when you need a Queue or a Stack.

    .NET has a similar yet deficient family of collections:

    • IList: Pretty much identical to Java’s List. Can be used as a Bag as well.
    • IDictionary: Pretty much identical to Java’s Map.
    • There is no “Set” equivalent in .NET. If you want a collection that guarantees no duplicates, you have to enforce that yourself (although there does exist a 3rd-party library that includes ISet; this library is included in NHibernate).

    The implementations are even more sporadic:

    • List: Equivalent to Java’s ArrayList.
    • Dictionary: A hash table, which makes it equivalent to Java’s HashMap.
    • LinkedList: Equivalent to Java’s LinkedList.
    • SortedDictionary: Equivalent to Java’s TreeMap.
    • SortedList: Despite the name, this is not a Sorted (Tree) implementation of IList. In fact it implements IDictionary and duplicates all of the functionality of SortedDictionary. It even has the same retrieval profile (O(log n)) of SortedDictionary; the only difference is in it’s memory usage (lower) and insertion/removal performance (slower). If you don’t want a key-value pair mapping, then you are forced to choose between the linear-focused List and LinkedList, both of which are O(n) for insertion and searching.
    • Queue: Is not an IList or IDictionary (just an ICollection), and doesn’t say much about its implementation / performance profile, although it’s probably a linked list under the covers.
    • Stack: Same as Queue, except it’s LIFO instead of FIFO, and has a different interface (which is also not shared with IList).

    In Java, I regularly used 5 different collection implementations depending on the circumstances; in .NET I only have 3 that are normally useful, and the gaps are not easily filled.


  5. Fashion Statement

    September 7, 2007 by Craig

    You’d think this would be an Onion story, but it’s legit:
    new battlefield clothing includes built-in tourniquets (via Engadget).

    Next up: underwear that doubles as a bodybag.


  6. Indexed

    September 4, 2007 by Craig

    Indexed is a pretty self-explanatory blog, once you see it.

    I like this one in particular, which Jessica Hagy did custom for Freakonomics Blog: