Three things have been bugging me lately about C#. Well one since I started using C# coming from writing a ton of unmaintainable Perl code. What C# needs:
- unless
- implies
- templates
unless
Unless is just a reversed if statement. Its actually quite simple and in some situations it improves code readability. This is personal opinion more so than anything else, but I feel strongly about it. Compare:
if (!property.CanRead) continue;
continue unless propery.CanRead;
So what it does is remove the negation from the if test (I mean, it is unless after all, isn't it?). It just flows better. "Oh, continue unless this condition is met."
implies
Extracting interfaces from existing classes is certainly easier with ReSharper, but I want more. I don't want to have to maintain separate interface files when the interfaces will match the implementation all of the time. I understand when you make interfaces and then code the implementation to them however that approach isn't always needed. I'll give a specific example: unit testing. I've started using StructureMap and Moq to significantly improve the quality of our tests, but in order to do that I had to StructureMap pluginify all of the IBATIS mappers we have written. In 100% of the cases the implementation of the mappers are the interfaces of the mappers, and now that I've gone and done this anytime a change needs to be made to a concrete mapper the interface will need to be updated as well - the dependency has been essentially reversed. I think this scenario will become more common as more people work to improve their unit tests, so I'd like to see something where:
public class PersonMapper : IPersonMapper { public Person Select(int id) { return null; } public IList<Person> SelectAll() { return null; } public void Create(Person p) { } public void Update(Person p) { } public void Delete(Person p) { } } public interface IPersonMapper { Person Select(int id); IList<Person> SelectAll(); void Create(Person p); void Update(Person p); void Delete(Person p); }
public class PersonMapper implies IPersonMapper { public Person Select(int id) { return null; } public IList<Person> SelectAll() { return null; } public void Create(Person p) { } public void Update(Person p) { } public void Delete(Person p) { } }
So this isn't a solution for contract by design, its just the opposite, a tightly bound interface to a concrete class. But what it does do is reduce lines of code and increases maintainability and decreases the pain of writing good unit tests to a degree. And yes, a tool could be used to do this (I've wrote one in fact), but I'm talking maintainability and ease of use here!
templates
C# generics are very nice, but they are not templates. Many people who can better articulate the problem than I have argued for them so I'll just post my recent headache as my argument of why I want templates:
private static volatile INodeMapper nodeMapper;
public static INodeMapper Node() { if (nodeMapper == null) { lock (typeof(INodeMapper)) { if (nodeMapper == null) nodeMapper = ObjectFactory.GetInstance<INodeMapper>(); } } return nodeMapper; }
Because nodeMapper is declared volatile you cannot pass it using ref (or even out which would be less ideal than ref).
So imagine that code having to be written for every entity in your database. Again, a tool can do it, but that's not the correct answer to the problem. A preprocessor template here would be the only way to do what I want to accomplish in a sane manner. Until then I've used partial classes to break our mappers down to more maintainable levels (about 2000 lines of repetitious code into several smaller files alphabetically organized).