Generics vs. Duplication
I need to express the same logic over two different types. The code is literally the same in 90% of the cases, with minor modifications for each type. Seeking to avoid copy & paste programming, I decide to use some
public class BaseSpecificationController
<TSpecification, TSpecificationResult, TEntity> : BaseController where TSpecification : BaseSpecification<TEntity,TSpecificationResult> where TSpecificationResult : BaseSavedResult
The problem is that I got there, and it is really saving a lot of duplicated code. But still, I can't help but dislike such code, it seems like it is cheating.
.
Comments
Self-constrained generic base classes used to kind of freak me out... and then I kind of got over it and just use them where they are absolutely needed. They still look ugly, but at least I don't have to touch the base classes often enough to care.
generics are not easy (here we go again?), my approach is to keep them at the business layer as much as possible
Eber,
Using this approach, I managed to move 10 methods to a base class, instead of duplicating them.
We use generics/anonymous delegates very heavy here too (some times we take it a little bit too far just for fun to see how much shorter it can get, then have to take it a step back for readability), can't wait for C# 3.0 to make the code even shorter
Cheating?
I think you're feeling the same way procedural hardliners felt when they first learned about inheritance in OOP. They would all exclaim, "that's cheating!"
:D
I would not call it cheating. In fact, I wish generics would me more, well, generic, and, for example, allowed things like
template <class T, class U>
bool operator== (Foo<T> const& a, Foo <u const& b);
I periodically bump into various limitations of generic that force me to have duplicated code.
BTW, I sent you an e-mail a week ago with updated RemotingMock patch, and never got a response. I hope it did make it through the spam filter.
Ouch! Your blog thought <_U_> is an underline tag, while it was just a C++ template argument :-)
And it keeps underlying the rest of the page!
I am posting a closing tag just to put it out of its misery.
I wonder if this might be used as a security threat. E.g. if someone included some script tags and what-not
Cheating, as in, I am not sure that this gets me maintainable code over copy/paste
In 90% of the times I encountered heavy use of generics I've found it can easily be replaced with a non-generic alternative without any duplication. Perhaps if you provide more code a solution can be found...
Ivan,
If you would try to put script, it will error on you.
Hmm. Maintainability vis-a-vis redundancy vs. Maintainability vis-a-vis complexity. That IS an interesting quandary.
Personally I've find I can be guilty of over engineering things to fight code duplication. Based on this knowledge I try to avoid doing much when the duplication is very simple but in this instance you have 10 methods which sounds like a lot. On the other hand that code is a bit.. much.
More then likely you'll come back in 6 months and think this was either brilliant code or stupid code.. let us know which it is ;)
This is one of those contortions you have to go through because you are using a statically typed language. A dynamic language would usually make this kind of thing a lot easier because dynamic languages are obsessed, not with what an object IS, but what it is capable of DOING (functionally, or in terms of providing data).
I am not saying that anyone (including me) should switch to a dynamic language, I'm just saying, I've done both, and there are trade-offs, and this is one of the places where the statically typed abstraction "leaks" or gets in the way or both.
re: the unclosed underline tag... seems like it might be a bug with Subtext. I'll file a new bug report and see if we can get if fixed for the next release.
I've got to echo Bob on this one. Generics, AOP, codegen, even my own beloved IoC/DI, it's all one huge attempt to work around the limitations of a static typed language like C#. Simply Duck typing would lead to far cleaner code in your example. I love Neal Ford's quote on this:
"half of the code you write is just to make the compiler shut the hell up"
You feel like you are cheating when you write such code, but I feel this warm fuzzy feeling come over me when I see a really long type declaration filled with generic goodness. Generics are by farm my favorite feature added in .NET 2.0. Here is my favorite example from what I have done:
public struct Distance<T> : IMeasurement<T, DistanceUnitOfMeasure>, IComparable<Distance<T>>
where there is also
public interface IMeasurement<T, U> : INHibernateMeasurement<T, U>
The INHibernateMeasurement isn't really one that I like, but it was used at the time to have getters only on our Distances since a developer changing a value without touching the unit could be disastrous. We also didn't want to take the performance hit of using reflection on private members, so you have a explicitly implemented interface which allows setters as well as the normal getter only interface.
Anyway, that still gives me a warm feeling when I read it. Maybe I'm just sick?
Comment preview