I took a look at Google’s new language, Go. Some interesting stuff in there.
One idea in Go that would be especially handy in C# is implied interfaces. What does this mean?
Well, in C# you are accustomed to Interfaces. It’s a description of a type, without an implementation. I won’t go into why they are a good idea (think loose coupling).
A class (aka a Type) is said to satisfy an interface if it includes all the interface’s elements. So perhaps your IPerson interface requires FirstName and LastName properties. Then, when you implement an actual Person in C#, you will:
- Declare that the class implements IPerson (public class Person : IPerson)
- Implement IPerson’s properties in Person (public string FirstName { get; set; }, etc)
Those who have become accustomed to C#’s var keyword might recognize something here. By simply looking at the properties of Person, the compiler has all the information it needs to infer that Person implements IPerson. Why should I have to say so explicitly? Step #1 is logically superfluous.
Therefore I would like to see the interface declaration become optional.
You might choose to keep it in there as a convenience. For example, Visual Studio offers some nice tools to help you implement Interfaces. It might be nice to “state your intention” of implementing an interface, so that the compiler will stop you until you do – giving you red flags earlier. Error messages might be made more informative as a result. (That said, the tooling in VS could help you with implicit interfaces, too.)
But, unless I am missing something, the “: IPerson”syntax is not logically necessary. In the spirit of a more terse and “dynamic” style in C#, implicit interfaces would be a nice win.
An interesting proposal, but I believe that what you are proposing, and what Go is implementing, are rather different.
If I understand your proposal correctly — and I might not — you’re saying that at *compile time* we examine every class, compare it to every *known* interface (perhaps the set of all interfaces in all the referenced libraries and sources) and if a class happens to be a legal implementation of a particular interface, we make the class implement that interface, at compile time, as though you’d said to do so explicitly. (That there are infinitely many constructed generic interfaces poses an interesting problem, but that’s solvable through application of the method type inference algorithm generalized to work across every method of the interface; for each generic interface we’d identify finitely many "best fits".)
That’s different from Go, which is essentially implementing duck typing. An object that implements the right set of methods is treated as implementing any compatible interface *at run time*. The compiler doesn’t come into it; this is a *runtime environment* feature, not a *language feature*. The place you should be asking for this feature is the CLR, not the C# language, if you want something like Go.
Thanks Eric! I don’t know much about Go’s implementation, if you say it’s a runtime feature then I am inclined to believe it.
I do mean a language/compiler feature. The check happens at compile time, and yes, it would have to be checked against all known interfaces.
Perhaps there could be a way to limit the scope — one declares an interface to be "inferable". So the compiler doesn’t look against all interfaces, just the ones that you’d like to be implicit. That approach feels a bit half-assed, but it might be practical for performance reasons, and it gives the developer a bit more control.