Jacob Carpenter’s Weblog

July 21, 2008

C# reminder of the day

Filed under: csharp — Jacob @ 4:24 pm

Static data is not shared among constructed generic types.

That is, the final line of output from the following program:

using System;

class Program
    static void Main()
        NonGeneric.PrintCount(); // "Called 1 time."
        NonGeneric.PrintCount(); // "Called 2 times."

        Generic<int>.PrintCount(); // "Called 1 time."
        Generic<string>.PrintCount(); // ?

    public static void DoPrintCount(int count)
        Console.WriteLine("Called {0} time{1}.",
            count, count > 1 ? "s" : "");

class NonGeneric
    public static void PrintCount() { Program.DoPrintCount(++count); }
    static int count;

class Generic<T>
    public static void PrintCount() { Program.DoPrintCount(++count); }
    static int count;

Is “Called 1 time.”


July 16, 2008

Strange Framework design decision of the day…

Filed under: csharp — Jacob @ 3:19 pm

Today I encountered the strangest .NET Framework design decision I’ve seen in recent times:

HashSet<T>’s GetEnumerator method returns a public struct HashSet<T>.Enumerator.

Let’s count how many Framework Design Guidelines this violates:

1. Avoid publicly exposed nested types.

  • violation: duh.

Do not define a structure [instead of a class] unless the type has all of the following characteristics [including]:

2. It is immutable.

  • violation: calling MoveNext mutates the enumerator object.

3. It will not have to be boxed frequently.

  • violation: passing a HashSet<T> as a parameter to a method that accepts IEnumerable<T> (Linq, anyone?) will hide the class’ GetEnumerator method. Therefore, any calls to GetEnumerator call the interface method which requires boxing the HashSet<T>.Enumerator to return an IEnumerator<T>.

4. [Any others you see? Leave a comment.]


I really want to hear the arguments in favor of the shipping design.

Blog at WordPress.com.