What’s in a name? (C#’s hidden support for structural typing) (togaroga.com)

23 points by andrewhare ↗ HN
C# is well known for its nominative type system. This means that C# identifies types and their relationships based on their names. That is why C# does not allow you to create two types with the same name, even if they have a different public interface – the C# compiler only cares about the name of the type.

7 comments

[ 3.1 ms ] story [ 29.7 ms ] thread
How can I use this structural typing feature?

AOP weavers like postsharp let you do some duck typing like stuff by injecting interfaces as post compile step.

You could try reflection and/or dynamic. The latter requires .Net 4.
You could use Reflection to search for types based on structure. But there is no syntax for it.

Actually Linq + Reflection is some of the most entertaining code to write C#. Example: http://github.com/ecoffey/Bebop/blob/master/Bebop/BebopAppli...

we're saying there "Give me all the types out of a specific assembly that implement IResource".

I always found this somewhat inelegant. I suppose given all the constraints, its OK, but it feels like such a feature (such as the collection initializers) should be based on language constructs, not compiler special cases.
Lucian Wischik gave a really nice talk recently about language design at Microsoft and he indicated that they are trying to do it in that order from now on: determine the feature that's needed, add the necessary plumbing that would allow programmers to implement it, and implement it as a reference implementation.
I suspect the reason this works this way is because `foreach` is a language construct - not a part of the .NET Framework Class Library. On the other hand, `IEnumerable` is an interface defined in the class library that ships as part of the .NET runtime. Having the foreach construct require implementing IEnumerable will tie the compiler to a specific class definition. So instead, it only looks for a method with that name, which happens to be formalized in the class library in the form of an interface called IEnumerable.

Edit: hm.. but I note that this doesn't work for the using(){} construct.

This requires the object to implement an interface that is convertable to IDisposable instead of just looking for a `Dispose` method.