Without generics you cannot create a collection that avoids boxing with value types. But you can create specialized collections for concrete value types.
Here's an idea: Create your own version of ArrayList
but use T4 templates to generate specialized versions for every concrete type you care about. That gives you, without code duplication, an ArrayListInt32
, an ArrayListSingle
and so on.
This removes any performance penalty from the boxing and restores type safety.
Actually, Java has a similar problem because due to type erasure they cannot use generics to avoid boxing. They do have some specialized array list classes in newer versions. Thank god C# does implement true generics in recent versions.