I've seen a number of people suggest that you should encapsulate generic types with a class closer to your domain, for example Steve and Nat suggest in Growing Object-Oriented Software, Guided by Tests that:
Our rule of thumb is that we try to limit passing around types with generics [...]. Particularly when applied to collections, we view it as a form of duplication. It’s a hint that there’s a domain concept that should be extracted into a type.
In general, when is it a good idea to do something like this ..
class PersonList : List<Person>
.. rather than just using List<Person>
directly?
Use generic types to maximize code reuse, type safety, and performance. The most common use of generics is to create collection classes. The . NET class library contains several generic collection classes in the System.
In a nutshell, generics enable types (classes and interfaces) to be parameters when defining classes, interfaces and methods. Much like the more familiar formal parameters used in method declarations, type parameters provide a way for you to re-use the same code with different inputs.
So, anything that is used as generics has to be convertable to Object (in this example get(0) returns an Object ), and the primitive types aren't. So they can't be used in generics.
You can't inherit from the generic type parameter. C# generics are very different from C++ templates. Inheriting from the type parameter requires the class to have a completely different representation based on the type parameter, which is not what happens with . NET generics.
What you are looking for is a typedef
operator for Java or C#.
Unfortunately subclassing approach is not a good substitute for typedef
.
The following article "Java theory and practice: The pseudo-typedef antipattern" explains why in full detail.
I will copy verbatim the conclusion of that article here:
The motivation for the pseudo-typedef antipattern is straightforward enough -- developers want a way to define more compact type identifiers, especially as generics make type identifiers more verbose. The problem is that this idiom creates tight coupling between code that employs it and that code's clients, inhibiting reuse. You may not like the verbosity of generic type identifiers, but this is not the way to solve it.
I disagree with that philosophy. List<Person>
is a type just like PersonList
is. The domain concept of a list of persons is encapsulated in it just as well. If you ask me, it's better to use generics as much as possible unless using them limits you (see below) or makes the code hard to understand. For example, a function that works on PersonList
will be harder to generalize than one that works on List<Person>
, if you even notice that it's doing something general.
That said, specifically in Java there is a limitation on generics that makes them a lot less attractive. Due to type erasure, you cannot fully utilize generics when static methods / members of a type are involved, and you may need to extract a specific type that is not generic to be able to use it for certain things. Bottom line is, in Java you do need to extract a specific type in many cases, if that allows you to remain type-safe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With