Question

After looking at how Go handles interfaces and liking it, I started thinking about how you could achieve similar duck-typing in C# like this:

var mallard = new Mallard(); // doesn't implement IDuck but has the right methods
IDuck duck = DuckTyper.Adapt<Mallard,IDuck>(mallard);

The DuckTyper.Adapt method would use System.Reflection.Emit to build an adapter on the fly. Maybe somebody has already written something like this. I guess it's not too different from what mocking frameworks already do.

However, this would throw exceptions at run-time if Mallard doesn't actually have the right IDuck methods. To get the error earlier at compile time, I'd have to write a MallardToDuckAdapter which is exactly what I'm trying to avoid.

Is there a better way?

edit: apparently the proper term for what I call "safe duck-typing" is structural typing.

Was it helpful?

Solution

How can you know if a cow walks like a duck and quacks like a duck if you don't have a living, breathing cow in front of you?

Duck-typing is a concept used at run-time. A similar concept at compile-time is structural typing which is AFAIK not supported by the CLR. (The CLR is centred around nominative typing.)

[A structural type system] contrasts with nominative systems, where comparisons are based on explicit declarations or the names of the types, and duck typing, in which only the part of the structure accessed at runtime is checked for compatibility.

The usual way to ensure that duck-typing throws no exception at run-time are unit-tests.

OTHER TIPS

DuckTyping for C#

Reflection.Emit is used to emit IL that directly calls the original object

I don't think this library will give you compile time errors thought, I am not sure that would be entirely feasible. Use Unit Tests to help compensate for that.

I don't think there's another way in which you would get a compile time error.

However, this is something that Unit Testing is great for. You would write a unit test to verify that

DuckTyper.Adapt<Mallard, IDuck>(mallard);

successfully maps.

I know that implicit interfaces (which is what Go interfaces are) were planned for VB 10 (no idea about C#). Unfortunately, they were scrapped before release (I think they didn’t even make it into beta …). It would be nice to see whether they will make an appearance in a future version of .NET.

Of course, the new dynamic types can be used to achieve much the same but this is still not the same – implicit interfaces still allow strong typing, which I find important.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top