Friday, June 6, 2014

C# needs implicit interfaces

One of the things you must do when developing in C# is create objects. Then you want to unit test your system. Well, you suddenly need to use dependency injection and loose coupling. So you need to create an interface for that object. Now every time you modify that object you need to modify that interface. And that interface is essentially meaningless. The object really defines the contract and the interface is just a direct copy of it.

Interfaces are very useful. You define a contract and then objects can meet that contract. But most interfaces are really built around a single implementation of that contract and exist to allow mocking and dependency injection. So this problem stems from the tight binding between an object and it's contract. This binding is the problem that requires interfacing everything to fix.

Here is a simple fix to the language:

public class FooObject : BarObject defines IFooObject {

    public void FooMethod() {
    }
    public void NonFooMethod() exclude IFooObject {
    }

}

This syntax allows you to have an interface automatically defined. This interface would include everything that was public except the constructor and any method marked with exclude. This simple syntax change is not complex and would save an enormous amount of time. It would remove countless meaningless files that exist only as a place to have code by out of sync.

Okay, now let me jump down the rabbit hole of type inference. Once you think of the interface as a automatically generated contract from an object you start thinking about the opposite direction. A method takes a set of objects as parameters (I am living in the world where everything is an object) and it places expectations on each of those objects. It defines a contract or interface of what it needs. Now the question becomes a comparison of the interface of the incoming object and the interface required for the parameter. Now this poops on the Interface Segregation Principle. ISP would say that the object should have a series of small interfaces for each method use. That's quite nice, but it also work. I like less work. The more automatic shit a machine can do for me the better. Especially because it will do things in a consistent and predictable way.

Now some things can not be determined. It is impossible to determine from a method the interface needed for its parameter. Just like it is impossible to determine if a program halts. But you can determine the parameter interface and whether a program halts in a large percentage of cases. In other cases, you can just say, "Beats me!" and issue a warning.

No comments:

Post a Comment