Generics in C# – Problems They Solve

cgenerics

I haven't used Generics in C# for a long while. Every time I think I need to use them I either go in the wrong direction and give up or find that I don't really need them. I feel that I'm missing out or ignoring a technique which could be useful and powerful.

I'm aware of how generics are meant to be used (or at least I think I am). If you have three methods that are all doing the same thing with different types, then using generics enables you to have just one method that will work with these three types.

EDIT (in response to comment)

Are there any code smells or patterns that I should be looking out for?

Note I use List<> a lot, so I'm not ignoring generics in the the standard library. It's just that I've not written custom code using Generics for a while.

Best Answer

Essentially, generics are a technique for aiding separation of concerns, or the single responsibility principle (SRP), as well as the DRY (Don't Repeat Yourself) principle. Without generics, you will sometimes see type or method names that reference both another type and a task, for example PersonCsvWriter, CustomerRecordSearch or ProductCollection. Unless these types derive from or consume other types that separate these responsibilities, then they are doing two things: e.g. PersonCsvWriter converts Person objects into sets of fields, and writes those fields to a CSV file. This makes your code harder to reuse. If you see this type of thing, it may be a code smell telling you that generics could be put to use.

I'd look out for this particularly if you are defining interfaces or abstract classes. Interfaces define roles in your application and don't make a lot of sense unless there can be multiple providers of that role. If the role is to work with other types, and the interface is not generic, it is very hard to re-implement it. For example, an IMapper<TFrom, TTo> is obviously a lot more reusable than a ICustomerToCustomerViewModelMapper.

You can of course be loosely-generic by treating everything as objects, using reflection and/or casting at runtime (as C#1 coders will remember). This isn't type-safe, having the obvious drawback of making your code harder to debug by allowing it to fail at runtime.