How Duck Typing Benefits C# Developers

0 comments suggest edit

David Meyer recently published a .NET class library that enables duck typing (also sometimes incorrectly described as Latent Typing as Ian Griffiths explains in his campaign to disabuse that notion) for .NET languages.

The term duck typing is popularly explained by the phrase

If it walks like a duck and quacks like a duck, it must be a duck.

For most dynamic languages, this phrase is slightly inaccurate in describing duck typing. To understand why, let’s take a quick look at what duck typing is about.

Duck Typing Explained

duck-rabbit-philDuck typing allows an object to be passed in to a method that expects a certain type even if it doesn’t inherit from that type. All it has to do is support the methods and properties of the expected type in use by the method.

I emphasize that last phrase for a reason. Suppose we have a method that takes in a duck instance, and another method that takes in a rabbit instance. In a dynamically typed language that supports duck typing, I can pass in my object to the first method as long as my object supports the methods and properties of duck in use by that method. Likewise, I can pass my object into the second method as long as it supports the methods and properties of rabbit called by the second method. Is my object a duck or is it a rabbit? Like the above image, it’s neither and it’s both.

In many (if not most) dynamic languages, my object does not have to support all methods and properties of duck to be passed into a method that expects a duck. Same goes for a method that expects a rabbit. It only needs to support the methods and properties of the expected type that are actually called by the method.

The Static Typed Backlash

Naturally, static typing proponents have formed a backlash against dynamic typing, claming that all hell will break loose when you give up static typing. A common reaction (and I paraphrase) to David’s duck typing project goes something like

Give me static types or give me death!

Now I love compiler checking as much as the next guy, but I don’t understand this attitude of completely dismissing a style of programming that so many are fawning over.

Well, actually I do understand…kinda. So many programmers were burned by their days of programming C (among other languages) and its type unsafety which caused many stupid runtime errors that it’s been drilled into their heads that static types are good, just, and the American way.

And for the most part, it’s true, but making this an absolute starts to smell like the monkey cage experiment in that we ignore changes in software languages and tooling that might challenge the original reasons we use static types because we’ve done it this way for so long.

I think Bruce Eckel’s thoughts on challenging preconceived notions surrounding dynamic languages are spot on (emphasis mine).

What I’m trying to get to is that in my experience there’s a balance between the value of strong static typing and the resulting impact that it makes on your productivity. The argument that “strong static is obviously better” is generally made by folks who haven’t had the experience of being dramatically more productive in an alternative language. When you have this experience, you see that the overhead of strong static typing isn’t always beneficial, because sometimes it slows you down enough that it ends up having a big impact on productivity.

The key point here is that static typing doesn’t come without a cost. And that cost has to be weighed on a case by case basis against the benefits of dynamic languages.

C# has used duck typing for a long time

Interestingly enough, certain features of C# already use duck typing. For example, to allow an object to be enumerated via the C# foreach operator, the object only needs to implement a set of methods as Krzystof Cwalina of Microsoft points out in this post

Provide a public method GetEnumerator that takes no parameters and returns a type that has two members: a) a method MoveNext that takes no parameters and return a Boolean, and b) a property Current with a getter that returns an Object.

You don’t have to implement an interface to make your object enumerable via the foreach operator.


A Very Useful Use Case For When You Might Use Duck Typing


If you’ve followed my blog at all, you know that I’ve gone through all sorts of contortions to try and mock the HttpContext object via the HttpSimulator class. The problem is that I can’t use a mock framework because HttpContext is a sealed class and it doesn’t implement an interface that is useful to me.

Not only that, but the properties of HttpContext I’m interested in (such as Request and Response) are sealed classes (HttpRequest and HttpResponse respectively). This makes it awful challenging to mock these objects for testing. More importantly, it makes it hard to switch to a different type of context should I want to reuse a class in a different context such as the command line. Code that uses these classes have a strong dependency on these classes and I’d prefer looser coupling to the System.Web assembly.

The common approach to breaking this dependency is to create your own IContext interface and then create another class that implements that interface and essentially forwards method calls to an internal private instance of the actual HttpContext. This is effectively a combination of the composition and adapter pattern.

The problem for me is this is a lot more code to maintain just to get around the constraints caused by static typing. Is all this additional code worth the headache?

With the .NET Duck Typing class, I can reduce the code by a bit. Here’s some code that demonstrates. First I create interfaces with the properties I’m interested. In order to keep this sample short, I’m choosing two interfaces each with one property..

public interface IHttpContext
  IHttpRequest Request { get;}

public interface IHttpRequest
  Uri Url { get;}

Now suppose my code had a method that expects an HttpContext to be passed in, thus tightly coupling our code to HttpContext. We can break that dependency by changing that method to take in an instance of the interface we created, IHttpContext, instead.

public void MyMethod(IHttpContext context)

The caller of MyMethod can now pass in the real HttpContext to this method like so…

IHttpContext context = DuckTyping.Cast<IHttpContext>(HttpContext.Current);

What’s great about this is that the code that contains the MyMethod method is no longer tightly coupled to the System.Web code and does not need to reference that assembly. Also, I didn’t have to write a class that implements the IHttpContext interface and wraps and forwards calls to the private HttpContext instance, saving me a lot of typing (no pun intended).

Should I decide at a later point to pass in a custom implementation of IHttpContext rather than the one in System.Web, I now have that option.

Yet another benefit is that I can now test MyMethod using a mock framework such as RhinoMocks like so…

MockRepository mocks = new MockRepository();
IHttpContext mockContext;
using (mocks.Record())
  mockContext = mocks.DynamicMock<IHttpContext>();
  IHttpRequest request = mocks.DynamicMock<IHttpRequest>();
  SetupResult.For(request.Url).Return(new Uri(""));
using (mocks.Playback())

You might wonder if I can go the opposite direction. Can I write my own version of HttpContext and using duck typing cast it to HttpContext? I tried that and it didn’t work. I believe that’s because HttpContext is a sealed class and I think the Duck Typing Project generates a dynamic proxy that inherits from the type you pass in. Since we can’t inherit from a sealed class, we can’t simply cast a compatible type to HttpContext. The above examples work because we’re duck type casting to an interface.

With C#, if you need a class you’re writing to act like both a duck and a rabbit, it makes sense to implement those interfaces. But sometimes you need a class you didn’t write and cannot change (such as the Base Class Libraries) to act like a duck. In that case, this duck typing framework is a useful tool in your toolbox.

Technorati tags: Duck Typing, Dynamic Languages, C#, Dynamic Types

Found a typo or error? Suggest an edit! If accepted, your contribution is listed automatically here.



42 responses

  1. Avatar for Rob Conery
    Rob Conery August 19th, 2007

    I dunno... duck-type loosey-goosey barnyard programming is much more of a stylistic approach than C# will let you have. In other words, we're taught to program against types - so when we create a method, we make sure the parameters specify the types we need to work.
    Duck typing doesn't care (as you mention above) - it only needs to be capable of certain behavior. To me this is a core difference of a functional language.
    Ruby classes are defined by what they "do", not what they are. You can write code against this principal for testing. A classic example is string concatenation:
    def append_words(word1, word2)
    if word1.respond_to (:<<) && word2.respond_to (:<<)
    word1 << word2
    else ("can't append these values")
    This type of coding is more of a mindset than anything - and my point with this ramble is that wedging duck typing into C# is sort of going against it's "thang".

  2. Avatar for Haacked
    Haacked August 19th, 2007

    Well if it quacks like a duck, and if it... you get the picture. I'm well aware of the stylistic differences between a dynamic language and a statically typed language like C#.
    My point is that there are benefits to using duck typing, even if it's an impaired not quite complete version of it, within C#.
    As I demonstrated, there is a real world use case for its use.

  3. Avatar for James McKay
    James McKay August 19th, 2007

    Just a thought: performance issues aside, wouldn't duck typing make the whole concept of generics redundant?
    Or, to put it another way, are generics something of a workaround for the fact that C# has hitherto lacked full support for duck typing?

  4. Avatar for Damien Guard
    Damien Guard August 19th, 2007

    My worry with duck typing is that two methods with the same signature do not necessarily do the same thing.
    Say you pass an object to a function that expects that object to supports a Remove property.
    A Collection class and a File class would have radically different ideas as to what Remove should do - one would be destructive, the other not.
    The Mac Cocoa system gets round this by using messages where parameter names form part of the signature but whilst C# method names remain so short it seems like a recepie for the odd catastrophic bug.

  5. Avatar for Ian Griffiths
    Ian Griffiths August 19th, 2007


    "(also known as latent typing)"

    should have read:

    "(also sometimes incorrectly described as latent typing)"

    Latent typing and duck typing are not the same. Latent typing simply means that a type exists, but is not explicit. Duck typing is really just structural typing. In the languages currently making duck typing popular, it is achieved by performing type checks at the point at which members are used, and 'type compatibility' in this case simple means 'has a matching member'.
    Not the same concept at all, really.
    More on my campaign to stop people misusing the term latent typing here:

  6. Avatar for Steven Harman
    Steven Harman August 19th, 2007

    Just to be completely nit-picky and in spite of the fact that I realize the above code is contrived solely for this post... the implementation of MyMethod breaks the Law of Demeter.
    Pretty sad for a guy who just wrote a whole blog post on the Laws of Software Development. :)

  7. Avatar for The Other Steve
    The Other Steve August 19th, 2007

    "But sometimes you need a class you didn’t write and cannot change (such as the Base Class Libraries) to act like a duck."
    Why not use an adapter?

  8. Avatar for Jacob
    Jacob August 19th, 2007

    Why not use TypeMock? It allows you to mock sealed classes just fine without all the guff of other mock frameworks. You want to mock HttpContext, then mock HttpContext. If all you want to do is mock HttpContext.Request, you can do that easily as well without messing with ducks or any other barnyard animals.

  9. Avatar for Haacked
    Haacked August 19th, 2007

    @Jacob TypeMock sounds great for mocking the HttpContext if that were my only goal here, but that's not my goal here and I only mentioned that as an afterthought.
    This is an issue of code design. I want to decouple my code from HttpContext and promote loose coupling. Controlling my dependency graphs makes it easier to write maintainable code.
    This came up one day when I wanted to write a command line tool for Subtext and noticed that my dependency graph required me to import just about ever assembly ever created. I would've liked to simply pass in a different context. Duck Typing provides a simpler way to do this.
    @The Other Steve - I could write an adapter, but why write more code when I can get it done in less with duck typing? Duck typing won't fit all situations, but when it does, it's a nice toolkit to have in your toolbelt. That's all I'm saying. I'm not advocating everyone to go out and rewrite every adapter to use duck typing.
    @Damien but the same can be said of two classes that implement an interface. That doesn't magically provide semantics for how the code should act. In fact, sometimes classes don't implement the full interface and throw NotImplemented exceptions when calling a method (some Stream implementations are an example).
    The key here is that the burden is ultimately on the developer to be aware of what she is doing and to write tests to validate assumptions on how the code is actually acting, rather than blindly trusting that a method called quack does quack in the way she wants. Likewise she can't simply trust that the method quack of IDuck quacks in the way she wants either.

  10. Avatar for deft flux
    deft flux August 19th, 2007

    Great post by Phil Haack

  11. Avatar for Scott
    Scott August 19th, 2007

    "The key here is that the burden is ultimately on the developer to be aware of what she is doing"
    Which is completely antithetical to static typing. Usually the argument against dynamic typing, which is very different from dynamic dispatch (Ruby, Smalltalk, and Objective C are really dynamic dispatch, message based systems rather than dynamically typed), goes like this: "But what if some other programmer passes in the wrong object? I want the compiler to make sure that this type and only this type can be passed to my code.".
    At which point I say, "Boy, you need to hire some smarter programmers. Who are these other programmers anyway?"
    The duck typing class looked interesting, but it also seems like a giant reflection macro. ;)

  12. Avatar for Haacked
    Haacked August 19th, 2007

    @Scott Ain't nothing wrong with a giant reflection macro. ;) I love incremental improvements.

  13. Avatar for Haacked
    Haacked August 19th, 2007

    @Scott though I should point out it's a bit more than a reflection macro with its support for covariance, contravariance, and static casting. The feature list on the page is interesting.

  14. Avatar for John Lam
    John Lam August 20th, 2007

    See this other post on duck typing from TomasP, one of the devs on the Phalanger project:

  15. Avatar for British Inside
    British Inside August 22nd, 2007

    The funny thing (I suppose I should be embarassed, but I&amp;#39;m not) about the recent post &amp;quot; How

  16. Avatar for Console.Write(this.Opinion)
    Console.Write(this.Opinion) August 27th, 2007

    Resumo da semana 28/08/07

  17. Avatar for wight
    wight September 8th, 2007

    It seems that static typing is generally better for low-level code, as it is tied to low-level representations.
    In contrast, duck typing generally seems better for high-level code because it is manipulating abstract objects rather than low-level representations.
    I think there is already a form of duck-typing in C++ which is often overlooked. Templates are essentially duck-typed, since they can accept any type which supports the methods needed by the template. However, they would be better described as "static duck typed" as opposed to "dynamically duck typed".

  18. Avatar for you've been HAACKED
    you've been HAACKED September 9th, 2007

    IHttpContext And Other Interfaces For Your Duck Typing Benefit

  19. Avatar for Kirill Osenkov
    Kirill Osenkov September 9th, 2007
  20. Avatar for Ricardo Stuven
    Ricardo Stuven September 24th, 2007

    While duck typing doesn't exactly match the concept of structural subtyping, I think they help to solve the same problems, as well summarized in the presentation "Combining Structural and Nominal Subtyping" by Donna Malayeri:
    - Don't need to name [under different interfaces] all possible combinations of interesting methods.
    - Don't need to specify that a class implements a particular interface ahead of time.
    - Easy to later define new subsets of methods that are interesting.

  21. Avatar for ASPInsiders
    ASPInsiders October 3rd, 2007

    The funny thing (I suppose I should be embarassed, but I&amp;#39;m not) about the recent post &amp;quot; How

  22. Avatar for ian
    ian November 3rd, 2007

    hey thx to your advices..i've done my project...!!!!!!

  23. Avatar for .tyler
    .tyler December 3rd, 2007

    Duck Typing Saves You Some Typing

  24. Avatar for David
    David December 13th, 2007

    You completely missed Damien's point. When a class declaratively implements an interface, it is declaring that it not only that it implements members with the same signatures, but that those members correspond to the behavior set forth by the interface. These behaviors cannot be enforced by the compiler of course, but they are an understood prerequisite of interface programming. By designing a method that takes an ICollection<T> as an argument, I am not only requiring the argument to have Add and Remove methods, but also that those methods behave in a particular way. If you try to pass in a type that has Add and Remove methods, but doesn't implement ICollection<T> (i.e. a type that has not declared that its behavior is compatible with ICollection<T>), the compiler will stop you.
    When you use duck typing, you throw all that away. Any class can be used in any context as long as the signatures match; but signatures are only part of the equation. Of course, strict typing creates its own problems (what happens when an existing class doesn't explicitly implement an interface, perhaps from another assembly, even though its behavior is compatible?). But duck typing, especially in the form in which it is currently being forced upon developers in C# 3.0, is not the answer; it merely trades one set of problems for another.

  25. Avatar for Haacked
    Haacked December 13th, 2007

    With all due respect, I don't think I missed his point. As you point out, there's no way to specify the expected behavior of an interface. Perhaps with new language features such as Spec#, you can specify a contract for the interface and get tighter control over how implementers really implement that interface.
    But the fact of the matter is, when you expose an interface, you have certain semantics you expect. For example:

    public interface Foo
    void Add(string id, string value);
    object Get(string id);

    With that interface, you'd expect after calling Add, that a subsequent call to get with the same id returns the object I added in Add.
    However, it is still incumbent on me, as the implementer of that interface to provide behavior that matches that expectation. The only way I can do that is to test my implementation with your code. I may implement it in an exotic manner.
    Now whether I implement it with a new class, or whether I implement it by using duck typing with an existing class, it's really none of your business as the one writing the interface.
    As long as I meet your contract, it doesn't matter. So either way, it's still incumbent on me to make sure I'm implementing the interface in the correct manner.
    Let's look at the inverse. Suppose that interface is supposed to build a composite structure. So in practice, you call Add multiple times. When the structure is complete, only then does Get return something. Now my implementation of your interface is incorrect.
    Moral of the story:
    1. Interfaces don't define enough contract.
    2. You're on your own as an implementer of the interface, no matter how you implement it.
    3. You better test your assumptions (ie test your implementation of the interface in the context it was meant to be used).

  26. Avatar for David
    David December 13th, 2007

    Once again you have missed the point :)
    Declaritive interface implementation has nothing to do with helping the implementer. You're right; you are responsible for implementing the stated requirements, regardless of the syntax involved. Declaritive interface implementation is about helping the consumer. The point is, you do your due diligence, you design and test your class, and when you are done, you declare that your class is compatible with an interface by declaritively implementing it. Then when I say that method Foo needs an instance of a type which implements IBar, and you have declared that your Bar class implements IBar, a consumer can have confidence that your class will meet the needs of the Foo method (depending on his degree of trust in your implementation).
    On the other hand, when you start using duck typing, all bets are off. There is no due diligence, there is no declarative implementation, and there is no way for a consumer to know whether a particular method or set of methods correctly fulfills a given set of requirements. All you have is a set of member signatures, which tell you absolutely nothing. Even with good documentation (which is rare), the consumer probably will not have enough information to know whether your type will do the job, because you as the class designer have not had the opportunity to compare the requirements of the interface to your implementation.
    Again, the biggest problem with requiring this kind of strict typing is that there are many cases when a particular class COULD implement a particular interface, it just doesn't; then you have to get into adapter classes, which require more coding and testing and raise their own design issues. But that doesn't mean that duck typing is the answer.

  27. Avatar for Haacked
    Haacked December 13th, 2007

    Perhaps I have. :)

    On the other hand, when you start using duck typing, all bets are off. There is no due diligence, there is no declarative implementation, and there is no way for a consumer to know whether a particular method or set of methods correctly fulfills a given set of requirements.

    This is the part I don't agree with. Why is there no due diligence? If I'm going to ducktype one type to another, I certainly will write tests, check my assumptions, etc... Perhaps even more so if I didn't write the class I'm attempting to cast to the interface.
    You seem to suggest that duck typing will cause me to go crazy with its power, suddenly forgetting good software practices, just slapping things together willy nilly.

  28. Avatar for David
    David December 14th, 2007

    " due diligence..." was perhaps a misstatement. What I was trying to say was that duck typing moves the responsibility for the due diligence from the class designer (who under a strict typing system is forced to declare whether a type is compatible with a particular interface) to the class consumer, who is much less likely to fully understand all of the ramifications and unintended consequences of a particular implementation, since they don't have access to its internals. Documentation will only take you so far.
    It also seems to me that duck typing removes the concept of black box implementation. For example:
    interface IBar { void Bar1(); }
    void Foo(IBar a) { a.Bar1(); }
    In the static type system, you have to pass an instance of type IBar to method Foo. With duck typing, you have to pass an instance which has a Bar1 method. Now, when you're writing your duck-typed application, you are aware of the Bar1 requirement, and you test for it, and make sure that everything works correctly.
    Now in a future version of the My.Bar library, the IBar interface changes:
    interface IBar { void Bar1(); void Bar2(); }
    void Foo(IBar a) { a.Bar1(); a.Bar2(); }
    Yes, its a breaking change; guess what, they do happen! Now, in a static type system, the Bar which implements IBar and that I was passing to Foo will have to be updated to include a Bar2 method, and in the process I as the designer of the Bar class will make sure that it still meets the requirements of the IBar interface.
    But in a duck typed system, there is no opportunity to do this kind of verification. Foo has added a requirement that a should include a Bar2 method; if it already does, it will be called, regardless of whether or not it is actually appropriate.
    This goes back to my original point; duck typing relies completely on member signatures for binding, but they don't tell the whole story. Frankly, this to me is precisely why static typing exists in the first place, and I am at a loss to explain why some people think that using a system which invites unseen breaking changes is a good thing.

  29. Avatar for Haacked
    Haacked December 14th, 2007

    Well you can't really "change" an interface. What you've shown is creating a new interface that just happens to be the same name as the original interface. But it is a new interface. If you're in the habit of deploying such a change without recompiling clients, then I, as a client of your assembly, probably have much more to worry about than the off chance that the new method you added to the interface just happens to match my duck typed method.
    Fact of the matter is, it won't matter until I recompile. As far as my client is concerned, it is compiled against your original interface, not the new one. So calling Bar2 does nothing until I recompile my client.
    And when I do, I'll be sure to test to make sure I'm still fulfilling whatever contract is necessary. If not, then I'll do something other than duck typing.
    It's really the same boat as an interface implementer. You changed the interface, how do I know you didn't change the semantics of the original method along with adding the new method? I have to re-evaluate all my assumptions whether or not I'm using duck typing.

  30. Avatar for David
    David December 17th, 2007

    Of course you have to recompile. I thought that was obvious from my example. But that's my whole point: when you recompile, you will not receive any errors or warnings that might indicate to you that the contract for the method Foo has changed, even though it clearly has. You seem to imply that this isn't a big deal, because you'll just "test to make sure [you're] still fulfilling whatever contract is necessary." Perhaps you are under the impression that testing has no cost and is 100% effective? That has not been my experience.
    It is indeed somewhat similar to the problem of the interface implementer, but again, that is my point. Rather than the interface implementer changing the class to guarantee that it correctly implements the interface, and then ALL consumers receiving the benefit of that change, with duck typing, it is up to every individual consumer, first to find all of the potential breaking changes (which is far from trivial, especially given the lack of help from the compiler, as mentioned above), and then to figure out how to fix each of them individually. That is what I meant by removing the black box concept.

  31. Avatar for Haacked
    Haacked December 17th, 2007

    @David Let's revisit your first IBar interface example with one method. Suppose I have implemented the interface with my own class Foo:

    public interface IBar
    void Bar1();
    public class Foo : IBar
    public void Bar1() {}
    public void Bar2() {}

    In this case, Bar1() implemnets the interface, Bar2() is just some method I have on the class for other reasons.
    Now you go and add Bar2() to the IBar interface and I recompile. Egads! I got no warning, yet Bar2 doesn't reasonably satisfy expectations for the interface.
    Conclusion? Interfaces are dangerous.
    Hardly! The conclusion is that anyone can come up with extremely unlikely edge cases and point to them as a problem with a particular style of development.
    Software is fully of tricky potholes, some more common than others. Compiler checking is on a tiny sliver of validation for code. While it can be helpful, having a decent automated test suite covers a lot more cases than a compiler could ever cover. Testing isn't perfect and won't catch everything, but it's better than leaving it just to the compiler which has no idea about your intentions.

  32. Avatar for David
    David December 20th, 2007

    But again, as the interface implementer it my responsibility to know when the interface has changed and respond accordingly. Its about putting the responsibility in the right place. Dynamic languages in general put more responsibility on the end programmer instead of the class/library designer where it usually should be. That doesn't mean that the end programmer shouldn't be responsibile for verifying their programs, but the first responsibility is on the class designer.
    A "decent" automated test suite is very difficult and expensive to create and maintain, and even then it only covers a limited number of cases. That doesn't mean its not worth using, but when I am creating a highly reliable mission critical system, I need every advantage I can get, including very strict compile time checking. Intentionally opening myself up to bugs by using dynamic language features which emphasize programmer convenience over program correctness is a good way to get myself fired.
    Your example does indicate one of the few things that I like better about VB.NET than C#, which is that interface implementations should have to be explicit. The C# team was careful to mitigate the "brittle base class" problem, but for some reason they left this "brittle interface" problem, which is just another flavor of the same problem.
    And if you really think that the situations that you and I outlined are edge cases, then you must not be dealing with the daily challenges of enterprise application development.

  33. Avatar for Justin Chase
    Justin Chase June 24th, 2008

    Just use Boo :) statically typed with compiler level duck type support.
    Here is an example:

  34. Avatar for Pete Hurst
    Pete Hurst September 3rd, 2008

    Nice to see some good cases for duck typing (a day or two after I had a rant on another blog, akin to "Duck typing? Sounds more like Duct Taping...")
    Especially interesting how the foreach is actually implented in such a way.
    I think a great number of times Reflection is used to achieve basically the same goal.
    Unfortunately (a bit like Reflection) it's a dangerous tool unless wielded very carefully.
    Really, if the main use case is a workaround for the initial poor architecture of .NET - and in fact the existence of "sealed" in the first which seems like the most backward keyword ever - then is this really a good thing to tout?

  35. Avatar for Justin Chase
    Justin Chase October 3rd, 2008

    Perhaps you already know this but just in case, you may be interested to hear about Boo which is a statically typed language that runs on the CLR and implements duck typing.
    Basically you can declare your variable as type "duck" and the compiler will let you call methods that may or maynot exist on the real type. Additionally, if your instance implements the interface IQuackFu but does not implement the member you are trying to call it will forward your call to this interface instead. Here is an example I made that uses duck typing to drill into an XML document as if it were an object:

  36. Avatar for Anders
    Anders October 9th, 2008

    I think duck typing should be implemented with the use of 'as'.

    IHttpContext context = HttpContect.Current as IHttpContext;

    And if the cast fails it should return null as expected.

  37. Avatar for Chris Christodoulou
    Chris Christodoulou December 23rd, 2008

    Unsurprisingly, interface designers can never imagine all the possible applications of their code. They usually succeed in making us do more work than is necessary to adapt their tool to our use. If I see a bunch of semantically consistent and related objects with really lax or unimaginative interface design and I want to apply my superior foresight but recycle the grunt work why should anybody stand in my way. Wrap the whole thing in {unsafe_duck_bs} and let me proceed. Back in the C days you could shoot yourself without even trying. Now, I'm prevented from even owning the gun, lest I harm myself. This reminds me a lot of the modern IT guy. He removes all the usability from the software and proclaims the enterprise is safe from all threats. Why should he care that we can't do any real freaking work. Remember your roots people. If we came from C and developed all this great stuff providing judicious use of "power tools" in a language is not a sin. Loosen up a little.

  38. Avatar for Subodh
    Subodh December 17th, 2009

    If I need to have two different interfaces implemented (with identical signature on one or more of the methods), how would duck typing help?

  39. Avatar for Myster
    Myster June 10th, 2010

    Say I have a 'Duck' object and I have a 'DeformedDuck' object, the DeformedDuck, does not implement Quack() but does imlement MakeSound() ... I control neither.... is there some way I can treat them the same?

  40. Avatar for Myster
    Myster June 10th, 2010

    It looks like the DuckType.Cast does not check for the extension method which would make my DeformedDuck able to quack. :-)

  41. Avatar for Jason Colter
    Jason Colter November 9th, 2014

    I tried using the code in this article and found that it only works with public classes and does not work with anonymous types. So I was inspired to create a similar component that works with anonymous types. You can read the details on my blog but essentially it will allow you to do the following:

    var developer = new { Name = "Jason Bowers" };
    var foo = developer.DuckCast<ideveloper>();

    Great article!

    Thank you.

  42. Avatar for David Lewis
    David Lewis November 9th, 2016

    How is this scenario significantly different for a manually written proxy class? If you write a proxy to support unit testing and the class you are consuming with that proxy changes in a way that does not alter the portions of the interface your proxy interacts with the same problems exist. Adding void Bar2() would not trigger compile time warnings or errors in a proxy that only uses void Bar1().