David Hayden [MVP C#]

Sponsors

The Lounge

Wicked Cool Jobs

News

  • CodeBetter.Com Home

Other Links

Teas

Patterns & Practices

Florida .NET Developer

Book Reviews

Tampa ASP.NET MVC Developer Group

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Using the new and class keywords with .NET Generics

The other day I was digging through some source code and stumbled upon something similar to this:

 

public class ObjectFactory<T> where T : new()
{
    public T Construct()
    {
        return new T();
    }
}

 

I was curious what the generic constraint new() meant, but didn't have time to investigate so just scribbled on the whiteboard in my office to investigate it over the weekend.

Fast forward to this weekend. Saturday ( today ) was an unbelievable beautiful day in Sarasota, Florida and the kids and I decided to spend most of the day playing in the backyard. During my breaks I was reading How to Code .NET: Tips and Tricks for Coding .NET 1.1 and .NET 2.0 Applications Effectively.

There is a chapter in this book, called Using the new and class keywords with .NET Generics, which preceded to explain that the new() constraint meant the type must have a parameterless constructor. Sweet! Cross that question off the list.

The book then started to dive into IL and talk about the performance implications of including the class constraint as follows:

 

public class ObjectFactory<T> where T : class, new()
{
    public T Construct()
    {
        return new T();
    }
}

 

Although sadly I hadn't thought about it, without the class constraint, the compiler doesn't know if the type T is a value type or reference type and hence has to check for both.

So I am hanging out having fun with my kids, but there is a nagging desire in the back of my head to run ildasm and look at the IL for myself. And, yeah, there is a difference. Here is the IL when you don't include the class constraint:

 

.method public hidebysig instance !T  Construct() cil managed
{
  // Code size       38 (0x26)
  .maxstack  2
  .locals init ([0] !T CS$1$0000,
           [1] !T CS$0$0001)
  IL_0000:  nop
  IL_0001:  ldloca.s   CS$0$0001
  IL_0003:  initobj    !T
  IL_0009:  ldloc.1
  IL_000a:  box        !T
  IL_000f:  brfalse.s  IL_001c
  IL_0011:  ldloca.s   CS$0$0001
  IL_0013:  initobj    !T
  IL_0019:  ldloc.1
  IL_001a:  br.s       IL_0021
  IL_001c:  call       !!0 [mscorlib]System.Activator::CreateInstance<!T>()
  IL_0021:  stloc.0
  IL_0022:  br.s       IL_0024
  IL_0024:  ldloc.0
  IL_0025:  ret
} // end of method ObjectFactory`1::Construct

 

and here is the code when you do include the class constraint:

 

.method public hidebysig instance !T  Construct() cil managed
{
  // Code size       11 (0xb)
  .maxstack  1
  .locals init ([0] !T CS$1$0000)
  IL_0000:  nop
  IL_0001:  call       !!0 [mscorlib]System.Activator::CreateInstance<!T>()
  IL_0006:  stloc.0
  IL_0007:  br.s       IL_0009
  IL_0009:  ldloc.0
  IL_000a:  ret
} // end of method ObjectFactory`1::Construct

 

When you include the class constraint, we jump immediately into Activator.CreateInstance because we know the type T is not a value type. I won't lose sleep at night if I forget the class constraint when I only mean reference types, but certainly I am performance conscious and will include the class constraint in code where I am definitely assuming T is a reference type.

Also, if you have never played with SqlCommandBuilder.DeriveParameters, I also played with it this weekend:

by David Hayden


Posted Sat, Nov 4 2006 5:29 PM by David Hayden

[Advertisement]

Comments

PuntoRete wrote Generics e il constraint new()
on Sun, Nov 5 2006 4:57 AM
Web Log di Adrian Florea wrote Default constructor and not nullable value type generic parameter constraints
on Sun, Nov 5 2006 4:00 PM
Jeremy D. Miller wrote re: Using the new and class keywords with .NET Generics
on Fri, Nov 17 2006 4:57 PM

Thank you David.  You just saved me some work this evening with this post.

Devlicio.us