C#: System.Object vs Generics
I'm having a hard time understanding when to use Object (boxing/unboxing) vs when to use generics.
For example:
public class Stack
{
int position;
object[] data = new object[10];
public void Push (object o) { data[position++] = o; }
public object Pop() { return data[--position]; }
}
VS.
public class Stack<T>
{
int position;
T[] data = new T[100];
public void Push(T obj) {data[position++] = obj; }
public T Pop() { return data[--position]; }
}
Which one should I use and under what conditions? It seems like with the System.Object way I can have objects of all sorts of types currently living within my Stack. So wouldn't this be always preferable? Thanks!
Always use generics! Using object's results in cast operations and boxing/unboxing of value-types. Because of these reasons generics are faster and more elegant (no casting). And - the main reason - you won't get InvalidCastException
s using generics.
So, generics are faster and errors are visible at compile-time. System.Object
means runtime exceptions and casting which in general results in lower performance (sometimes MUCH lower).
A lot of people have recommended using generics, but it looks like they all miss the point. It's often not about the performance hit related to boxing primitive types or casting, it's about getting the compiler to work for you.
If I have a list of strings, I want the compiler to prove to me that it will always contain a list of strings. Generics does just that - I specify the intent, and the compiler proves it for me.
Ideally, I would prefer an even richer type system where you could say for example that a type (even if it was a reference type) could not contain null values, but C# does unfortunately not currently offer that.
While there are times when you will want to use a non-generic collection (think caching, for instance), you almost always have collections of homogenous objects not heterogenous objects. For a homogenous collection, even if it is a collection of variants of base type or interface, it's always better to use generics. This will save you from having to cast the result as the real type before you can use it. Using generics makes your code more efficient and readable because you can omit the code to do the cast.
It all depends on what you need in the long run.
Unlike most answers here, I won't say "always use generics" because sometimes you do need to mix cats with cucumbers.
By all means, try to stick with generics for all the reasons already given in the other answers, for example if you need to combine cats and dogs create base class Mammal and have Stack<Mamal>
.
But when you really need to support every possible type, don't be afraid to use objects, they don't bite unless you're mistreating them. :)
With the object
type, as you say you need to perform boxing and unboxing, which gets tedious very quickly. With generics, there's no need for that.
Also, I'd rather be more specific as to what kind of objects a class can work with and generics provides a great basis for that. Why mix unrelated data types in the first place? Your particular example of a stack emphasizes the benefit of generics over the basic object
data type.
// This stack should only contain integers and not strings or floats or bools
Stack<int> intStack = new Stack<int>();
intStack.Push(1);
Remember that with generics you can specify interfaces so your class can interact with objects of many different classes, provided they all implement the same interface.