Home > .NET CLR, Optimization, Runtime > Dangerous .NET CLR Quirk Lurks In Unfiltered Generic Methods

Dangerous .NET CLR Quirk Lurks In Unfiltered Generic Methods

Step right up! Step right up! Come inside and watch in horror as our sample C# code compiles, runs, and spectacularly fails right before your unbelieving eyes.

This sample code will compile, and run, and fail oh-so-epically:

using System;

namespace VirtualSpike
{

    class Program
    {
        // Internal static field.
        private static dynamic _singleton;
    
        // Singleton manager.
        public static dynamic YourFateSingleton<T>(T myT)
        {
            if (myT == null)
            {
                _singleton = default(T);
                return _singleton;
            }
            else
            {
                return _singleton;
            }
        }
        
        static void Main(string[] args)
        {
            var fate = Program.YourFateSingleton(DateTime.Now);
            Console.WriteLine("You will become fabulously rich at");
            Console.WriteLine("this exact date and time: {0}", fate);
        }
    }
}

Can you figure out why? (I’ll give you a hint: read section 12.9.4.3 of Jeffrey Richter’s “CLR via C#”)

 

(spoiler ahead)

 

If you suspect that the answer has something to do with the way the CLR implements generics, then you would be right. The CLR gives us the ability to filter our type variable, T, so that only specific set of types are eligible to become T. This is very important feature of the CLR’s generic implementation, and sets it apart from other languages.

When a generic method is not provided with a filter, both value types and reference types are permissible as values for T. This fact allows us to pass a DateTime object, which is a value type (viz., a struct), to our singleton’s factory method. Unfortunately for us, even though the runtime will never evaluate the null check, the C# compiler will not even so much as throw up a warning or an information message. As a result, our singleton will (silently) never get initialized for our DateTime parameter.

Hopefully, someday, the C# compiler team will break on the same error as it does for trying to set myT to null, or at least return a warning. Until then, be sure to set the filter to where T: class or avoid null checks in unfiltered generic methods.

Advertisements
  1. Mom
    03/08/2011 at 9:16 AM

    I have no idea what you are talking about, Zack, but I am impressed anyway! But then, isn’t that what Mom’s are for?

    • 03/19/2011 at 5:26 PM

      I agree with Mom 150%. Looking forward to the sequel (not to be confused with SQL). I sure am curious why we aren’t becoming fabulously rich… 😉

    • Zack
      03/28/2011 at 12:01 PM

      Thanks, Mom. (* – _ – *)

  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: