Peter said:
Ignacio Machin ( .NET/ C# MVP ) said:
Generics simply offer the mechanisn for you not to be forced to use a
"cover all instances type" type when you declare a class. [...]
But boxing/unboxing will still be there, forever and ever
I don't think so.
Well, boxing certainly won't be removed from .NET, for the obvious
practical reason that a ton of code already depends on it, and so does
much of the OOP design philosophy of .NET. All types derive from
System.Object, and the only way to do that without boxing would be to
make all types into reference types, which would kill performance.
Generics don't eliminate the need for, or usefulness of, boxing. Boxing
is necessary when you need to fit arbitrary values into one type;
generics eliminate some of those cases by constraining the type
automatically, but there are still times when generics are impractical
or don't help at all.
For example, the Tag property of visual controls is an object property,
so it can store a string, an integer, an instance of your own class,
etc., depending on how you want to use that particular control. Doing
that with generics would mean specializing each control class for each
possible tag type - you'd have Button<int> whose Tag property is an
integer, Button<string> to hold strings, etc... and even then, you'd be
limiting the usefulness of the class, because today the very same
button instance can hold an int one minute and a string the next.
Another example: the reflection methods to invoke a method dynamically
from a MethodInfo. You pass in the parameters as object[], which means
any value type parameters have to be boxed. How would you do that with
generics? Every element of the array has to have the same type, but the
method probably doesn't use the same type for each parameter. You might
think about replacing the single invocation method with a tedious
series of generic methods:
Invoke<A>(MethodInfo mi, A arg1)
Invoke<A,B>(MethodInfo mi, A arg1, B arg2)
Invoke<A,B,C>(MethodInfo mi, A arg1, B arg2, C arg3)
and so on
... but that introduces a number of problems: (1) you'd be limiting the
number of parameters you can pass to the method, because no matter how
many different versions of Invoke you write, each one still only has a
finite number of parameters; (2) you'd need to know the number of
parameters at compile time, whereas today the number of parameters is
determined at runtime by the length of the array you pass in; (3) you'd
complicate any code surrounding a call to Invoke, and probably
complicate Invoke itself, and certainly waste a lot of memory storing
all the different forms of the Invoke method and their specializations.
Jesse