Steve Michelotti

A .NET Developer's Toolbox

  Home  |   Contact  |   Syndication    |   Login
  201 Posts | 0 Stories | 1110 Comments | 51 Trackbacks


View Steve Michelotti's profile on LinkedIn

profile for Steve Michelotti at Stack Overflow, Q&A for professional and enthusiast programmers

Google My Blog

What I'm Reading:

Shelfari: Book reviews on your book blog

Tag Cloud


Post Categories



Generics are nothing new and have been part of .NET for over 5 years. Reference types and value types are core concepts in the CLR type system and these concepts have been the same since .NET was released – they are also nothing new. However, when I ask about these concepts during interviews, I often get a wide range in quality of the answers to these questions. If you get asked about these topics in an interview, be prepared to give great answers! You don’t have to give a textbook perfect memorized definition – but make sure you show that you fully understand and can apply the concepts to real-world development.

Question: why are generics such a big deal? I typically get answers discussing greater type safety and better performance. OK, the type safety one is pretty easy and straightforward. We had the ArrayList in .NET 1:

   1:  ArrayList list = new ArrayList();
   2:  list.Add(1);
   3:  list.Add(2);
   4:  list.Add("hello"); // compiler doesn't help me avoid!

When generics were introduced, we could declare a strongly-typed list of int’s to avoid this:

   1:  List<int> list = new List<int>();
   2:  list.Add(1);
   3:  list.Add(2);
   4:  list.Add("hello"); // compiler error!

So drilling into the second answer a little - *why* is performance better with generics? Often I hear, “you can avoid boxing and unboxing.”  OK great!  So what *specifically* is boxing and unboxing? (This is where people often start to struggle.)  Boxing is the act of converting a value type to a reference type. If we look at line #2 of the first code sample above, we’re putting an Int32 (a value type) into an ArrayList which stores everything as System.Object (a reference type). Therefore, unboxing is the act of converting a reference type to a value type (e.g., if we were taking an item out of the ArrayList and having to cast: int num = (int)list[0];). So with boxing/unboxing, don’t focus on casting or sub-classes (they’re not directly relevant!) – focus on converting from reference types and values types.

Question: what’s the difference between a reference type and a value type? Just focus on the basics: Reference types are stored in the heap (which means they are garbage collected) and value types are stored in the stack (cannot be allocated on the GC heap). Reference types can be null; value types cannot be null. Reference type variables do not contain the value – it has a pointer to its value. A value type variable contains the value itself.

Question: how do you know if a type is a reference type or a value type? Is a DateTime a reference type or a value type? A String? If you’re creating your own Person data structure, how can you control whether it’s a value type or a reference type? The short answer: a “class” is a reference type and a “struct” is a value type. If you “View Definition” in Visual Studio on a DateTime, for example, you’ll see:


DateTime is a struct so it’s a value type. System.String is a class so it’s a reference type (plus, the fact that it can be null is also a tip off that it’s a reference type). So if you create your own data structure as a class, it will be a reference type (as a struct, a value type).

For further reading on reference types, value types, and boxing/unboxing, have a look at this article by Jeffrey Richter written in December 2000. These are core concepts in the .NET type system that are still just as relevant today as they were 10 years ago.

Let’s circle back to our original generics performance question. So far we have 3 assertions:

  • Generics result in better performance because you can avoid boxing/unboxing
  • Boxing/unboxing is the act of converting between reference types and value types
  • A “struct” is a value type (e.g., DateTime); a “class” is a reference type (e.g., String)

Question: given all three of these assertions, is performance *really* better with a generic List<string> (string being a reference type) versus a non-generic list of strings? Answer: NO! Generics still provide *plenty* of benefit for these situations in terms of type-safety and allowing us to reduce noise in our code by avoiding having to cast objects (or code-gen objects if we want strongly-typed objects) – but a performance benefit is *not* on the list. However, if we’re talking about List<int> or List<DateTime> (value types) then here is a significant performance improvement. Not only is the run-time performance benefit significantly better because we can avoid the expensive boxing/unboxing operations, but we also avoid making the GC do extra work by having to collect these boxed objects that were just heap-based wrappers around what were originally value types.

In fact, let’s say you use 5 different generic List<T> in your application: List<string>, List<int>, List<DateTime>, List<Foo>, List<Bar> (where Foo and Bar are both reference types).  What happens behind the scenes is that the JIT will actually produce 3 versions of the generic list.  For each value type it will generate a totally strongly-typed version (so we’ll have 1 for List<int> and 1 for List<DateTime>). Then it will generate a single generic List<T> whose type gets re-used for all reference types behind the scenes (so it will get used for List<string>, List<Foo>, List<Bar>). But it is providing you the type-safety features along with allowing you to avoid all of the ugly casting in your code.

New .NET technologies come and go and as professional developers we are constantly working to learn and stay up-to-date on these new technologies. However, we also have to make sure we stay grounded in the fundamentals that .NET is based on. If you ever end up in an interview with me, I trust that you’ll ace these questions. :)  And, by the way, my company is hiring so if you’re interested, please contact me!

posted on Friday, August 6, 2010 9:35 AM


# re: Generics, Reference Types, Value Types, and Interview Questions 8/6/2010 12:30 PM George Stocker
When I interview candidates, I use generics as a weeder question. If they say they're an expert in C# 2.0, but can't give me specifics on generics (not just the textbook definition), that's a -1 from me.

# re: Generics, Reference Types, Value Types, and Interview Questions 8/6/2010 6:21 PM Gokul
I was thinking that I was an expert in .NET, only after reading your article I realized that there are lot of things that I should know. Simple and very informative article! please try to post articles like these discussing the core concepts in .NET

# re: Generics, Reference Types, Value Types, and Interview Questions 8/9/2010 1:24 PM Dan
We interviewed a candidate last week, and I asked a similar question with respect to generics. After a blank stare, I asked a simpler question: 'What's the difference between a class and a struct?' Again, a blank stare. After the interview, I recommended that we pass on the candidate. My boss disagreed and said 'I was being too hard on the interview candidates.' Too hard? Maybe I should consider interviewing... Thanks for the post...

# re: Generics, Reference Types, Value Types, and Interview Questions 8/10/2010 9:06 AM Vitaly
Lately I was asked even a better question: "What are the differences and similarities between generics in Java and generics in C#".

# re: Generics, Reference Types, Value Types, and Interview Questions 8/13/2010 12:39 AM Steve
@Vitaly - That *is* a good question (and one we .NET developers can take some pride in). A good case of: we didn't have it first, but perhaps we have it "better". :)

# re: Generics, Reference Types, Value Types, and Interview Questions 8/18/2010 1:13 PM Erik Lane
You interviewed me for a contract a couple of years ago and it was one of the better, and thorough, interviews that I've had...thankfully I did well enough for the job. Anywho, wanted to say I now use that as a template for when I interview candidates. Thanks Steve.

# re: Generics, Reference Types, Value Types, and Interview Questions 8/19/2010 11:36 PM Tao
Great article as always.
But performance improvement is still on the list for List<string> vs non-generic list of strings. It is just very small. Jeffrey Richter’s test program in CLR via C# 2nd Edition does performance comparison. By the way, read this book before coming to Steve’s interview.

# re: Generics, Reference Types, Value Types, and Interview Questions 8/20/2010 10:33 AM Steve
@Tao - The example in the Richter book (*awesome* book by the way - the "bible" for a .NET developer) shows the results 0.52 versus 0.53 seconds. To quote from the book, "Here we see that the times and number of garbage collections are about the same. So it doesn't appear that the generic List algorithm is of any benefit here." (page 363).

But don't take his word for it - run the test yourself and the results are *so* small they're really not statistically significant. You save some "castclass" IL calls by using the generic version but at this point we're splitting hairs. For this scenario, the benefits we get from generics is not performance but all the type safety and cleaner code that we get.

# re: Generics, Reference Types, Value Types, and Interview Questions 8/22/2010 1:55 AM Chuck
"Reference types are stored in the heap (which means they are garbage collected) and value types are stored in the stack (cannot be allocated on the GC heap)"

This popular statement is incorrect. Value types can be allocated on the heap sometimes (e.g. a value type field that's part of a class).

# re: Generics, Reference Types, Value Types, and Interview Questions 7/28/2011 10:33 AM Dexter
If you want to know more questions on C# please vist this site
C# Interview Questions

# re: Generics, Reference Types, Value Types, and Interview Questions 3/14/2013 3:20 AM ghj
good one!!

Post A Comment