Moderately Clever .NET Trick #1

programming No Comments

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).

Stupid .NET Tricks #5

programming No Comments

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.

Stupid .NET Tricks #4

programming 2 Comments

Consider this code:

public delegate void AnAction();

private static List getActions() {
  List actions = new List();
  for (int i = 0; i < 10; i++) {
    actions.Add(delegate() {
      Console.WriteLine("i is:" + i);
    });
  }
  return actions;
}

static void Main(String[] args) {
  List actions= getActions();
  foreach (AnAction action in actions) {
    action();
  }
}

If you run this code, you do not get a series of lines stating “i is: 0″ through “i is: 9″. You do not get any errors, warnings, or exceptions at either compile or run time either.

What you get is this:

i is: 10
i is: 10
i is: 10
i is: 10
i is: 10
i is: 10
i is: 10
i is: 10
i is: 10
i is: 10

When the delegate is added to the collection of delegates, it’s using the actual variable “i”, not the object that the variable is referencing at the time. (This applies for both reference and value types.) By the time the delegate collection is accessed and the actions are invoked, “i” has the value “10″ (which, by the way, is outside the normal operating range of the loop), even though “i” is no longer in “normal” scope.

This almost makes some sense, even though I think it’s counter-intuitive (and thus bug-encouraging). The .NET inventors had to choose between referencing the variable and referencing the value; there’s use cases for both. However, it starts getting really strange when you make a copy of the variable, as in this replacement code:

private static List getActions() {
  List actions = new List();
  for (int i = 0; i < 10; i++) {
    int x = i;
    actions.Add(delegate() {
      Console.WriteLine("i is:" + i + ", x is:" + x);
    });
  }
  return actions;
}

i is:10, x is:0
i is:10, x is:1
i is:10, x is:2
i is:10, x is:3
i is:10, x is:4
i is:10, x is:5
i is:10, x is:6
i is:10, x is:7
i is:10, x is:8
i is:10, x is:9

Upon invocation, the delegate references the variable “i” but the value of “x”. How and why it makes that choice is beyond me.

Stupid .NET Tricks #3

programming 2 Comments

C# made two big language improvements over Java:

  1. If you want to override a method, you have to explicitly declare the overriding method with the “override” keyword. The compiler complains if the keyword is omitted, or if there’s no overridable method with the same signature. This goes a long way to prevent accidental overrides and broken overrides. Note that this applies for abstract methods.
  2. Inheritance of a class or inheritance (implementation) of an interface are both indicated through the same keyword/operator: “:”. This differs from Java, which uses “extends” for the former and “implements” for the latter. Using a single keyword means that you can flip the superclass or interface from one to the other without changing code in the subclasses.

Both are great innovations, but the stupidity comes when you mix the two. The “override” keyword is only allowed when you’re subclassing; if you’re implementing an interface it is specifically disallowed. That means that you cannot, after all, easily flip the superclass to an interface (or vice versa) without changing the subclasses if the subclasses override any methods (in particular abstract methods, which are effectively the same beasts whether you’re subclassing or implementing an interface). So close…

Stupid .NET Tricks #2

programming No Comments

Say you want to compare two objects (typically for sorting). How do you do it?

You may want to consider the following:

  1. System.Collections.IComparer, an interface with a compare(Object, Object):int method. This is a direct take from Java’s Comparator interface, except with a worse name.
  2. System.Collections.Generic.IComparer<T>, a generic-friendly version of the above interface. Unlike the actual generic collections, it doesn’t inherit from the non-generic version of itself, so you can’t use one in place of the other without an adapter class.
  3. System.Collections.Generic.Comparison<T>, a delegate whose signature exactly matches the IComparer<T>’s only method. This effectively makes IComparer<T> unnecessary; you can pass around the Comparison<T> method instead of a full IComparer<T> and get the same results, except without the method naming restrictions of the interface.
  4. System.Collections.IComparable, another Java workalike. As in Java, it’s useful but misleading; it implies that there is exactly one means of comparing instances of the same class (Java calls this the “natural order” in a moralistic sort of way). IComparer is much more flexible system; IComparable is lazy and restrictive.
  5. System.Collections.Generic.IComparable<T>, another generic-friendly yet incompatible version.
  6. System.Collections.Comparer, “the default” implementation of IComparer which claims to do a case-sensitive comparison of arbitrary objects. Buh?
  7. System.Collections.CaseInsensitiveComparer, a case-insensitive version of Comparer (go figure).

That’s 7 types to be aware of, and only one that you should really ever use.

Stupid .NET Tricks #1

programming 5 Comments

I’m working on a .NET/C# project, which is a new environment/language for me after years of Java development. Thusfar, .NET appears to be a pretty decent language, although most of the good stuff in the language directly mimics Java. .NET did managed to fix a few of the problems with Java, but also failed to fix ones that could have been fixed without the burden of backwards compatibility.

The reason for my post though is that .NET has introduced a few new problems that shouldn’t exist. Microsoft, with all their resources and plans for language domination, really should have known better. I’m calling these “Stupid .NET Tricks” in homage to Letterman.

My first example is one that bugs me on a daily basis:

1. Properties are syntactic sugar for getter and setter methods, yet you can’t pass/assign the getter, setter, nor property itself to a delegate reference, even if the appropriate method would match the delegate’s signature.

For example:

public delegate int ValueGetter();
public void displayValue(ValueGetter getAValue) {
  if ( weReallyWantToDisplayTheValue() ) {
    int x = getAValue();
    display(x);
  }
}

private int aValue;
public int AValue {
  get { return aValue; }
  set { aValue = value; }
}

public void displayAValue() {
  // This isn't allowed, even though it makes perfect sense
  // displayValue(AValue);

  // Instead, you have to do this:
  displayValue( delegate() { return AValue; } );
}

Note that displayValue calls a method which calls a method on the property (both methods having the exact same signature), rather than just calling the method on the property itself.

Delegates are easily the best feature .NET has that Java doesn’t, but this oversight steals some of the thunder.

Checked Exceptions and Dependencies

programming No Comments

Eric Burke claims that check exceptions introduce implementation dependencies into your code:

Because the DAO throws PersistenceException, the next higher layer of your application must deal with it. This is a big problem, because this means your business logic now has persistence framework dependencies. What if you want to write a DAO that uses direct JDBC instead? Or you want to switch to Hibernate? Oops…every layer of your app depends on the old persistence API thanks to checked exceptions.

Here’s his sample code:

public class DefaultCustomerDao implements CustomerDao {
  public Customer findById(Integer customerId) throws PersistenceException {
    ...do something with the persistence framework that throws PersistenceException
  }
}

He claims that the calling code now has to know about PersistenceException, and that’s bad. He’s right on the surface of course, but I think he misses a point: the calling code already has to know about details of the persistence mechanism: it has to know about findById(), which in turn is a part of CustomerDao. (These classes are part of his fictional persistence framework that could be switched out for some other framework).

If you’re already dependent on CustomerDao and findByID() for your calling code, then adding a dependency on PersistenceException is not much worse. Thanks to the Law of Leaky Abstractions you’re probably more dependent on your persistence framework for more than APIs anyway; your code will almost certainly be structured around the API’s paradigm, so switching to another one will involve a lot of work regardless of whether it uses checked exceptions or not.

What you can do to minimize all this is to abstract your persistence mechanism behind a new API and paradigm that you control. This API would then call the API that does the actual work. You could swap out implementations of your API as you see fit (although due to the leaks it will still involve some recoding).

Under such a system, whether a framework uses checked exceptions is entirely irrelevant; it’s completely up to you whether you want to use them or not:

  • If it does, and you do, you can wrap its exceptions in your own, and gain interface independence.
  • If it does, and you do not, you can catch them in your API and then implement your own error-handling system (RuntimeExceptions or error codes).
  • If it does not, and you do, then you can work with its error-handling system (again, RuntimeExceptions or error codes) and throw your own checked exceptions as appropriate
  • If it does not, and you do not, then you can possibly get away with doing absolutly nothing (ie: letting the RuntimeExceptions propagate). You still have the same options as in point #2 as well.

I believe that your “real” code should be (at least) one abstraction away from any third-party library or framework, whenever possible. This gives you the least dependence on it should you want/need to change it down the road. Depending on the maturity of the library and the prevalence throughout your project, wrapping it in an abstraction layer is usually well worth the additional work: you gain flexibility (which is crucial in any project) and can “fix the problems” (as you define them) in the API as you go along.

(Perhaps surprisingly, this is my first Java-related post. What’s surprising is that I do Java for a living; I guess that I talk enough about it during the day that I don’t feel much need to blog about it on my own time :-P

Eclipse on OSX

programming, quote, technology No Comments

IM conversation between my boss (who recently got a new MacBook Pro) and myself:

Ted: gah!
Ted: eclipse is NOT a happy camper on OSX — crashes a LOT on stupid stuff like “refresh”
Craig: hrm
Craigo: good thing you don’t do any programming any more ;-)
Ted: ah ha ha
Craigo: “I’m a PC”
“And I’m a Mac”
“Hey PC, get your damn work done, I’ve got to go to a meeting”

C#.NET

programming No Comments

Microsoft really did themselves a disservice when naming their new programming platforms C# and .NET; they’re both nigh unto unsearchable. Many search engines drop “special characters” during their word parsing, which means that “C#” becomes “C”. Not only does that match two other languages, but it also matches any sort of line “c” (ie: used in an outline). “.net” of course matches the “.net” top-level domain, and also potentially the “net” used to catch fish. Google seems to figure out C# (it still chokes on .NET) but other site-specific search features don’t. Really annoying

Theme Changes

programming, web No Comments

Theme Change #0: Check to see if “Shaded Grey” is free-license enough for me to edit it. (I think about that sort of thing a lot these days). Hrm, looks like it isn’t; at least it’s not clearly demarcated enough for me to chance it.

Theme Change #0.5: Start working on a custom theme.

Theme Change #1: Get rid of the ugly border that’s the HTML/CSS default on hyperlinked images.

Next Entries »