8

Question

I've now read a lot about Duck Typing, and I seem to understand the concept.

What I've not understood is, in what case it does effectively make sense to abandon the benefits of strong typified programming to the benefits of Duck Typing. In what case would one use Duck Typing instead of Interfaces and Inheritance?

I mean if you anyway need to secure that an object passed to a Method implements certain methods, why shouldn't I simply define an Interface?

Just to be clear, I know how Duck Typing works. I want to know when it really makes sense to use it.

Clarification:

In which case would you use

public bool MyMethod(dynamic obj)

instead of

public bool MyMethod(ISomeInterface obj)
//or
public bool MyMethod(SomeBaseClass obj)
Community
  • 1
  • 1
LuckyLikey
  • 3,504
  • 1
  • 31
  • 54
  • 2
    Considering that in all .NET there are just four or five duck typings (`foreach`, `await`, LINQ, collection initializers), and they are all implemented compiler-side, I don't comprehend your question. – xanatos Jun 03 '15 at 11:41
  • http://haacked.com/archive/2007/08/19/why-duck-typing-matters-to-c-developers.aspx/ - there's a section here titled "A Very Useful Use Case For When You Might Use Duck Typing" – Alex Jun 03 '15 at 11:42
  • I believe you should change your question to "when to use dynamic keyword" – Dimitar Tsonev Jun 03 '15 at 11:45
  • "when it really makes sense to use it" - obviously, when you can't use inheritance, or inheritance is more expensive, than duck typing. – Dennis Jun 03 '15 at 11:46
  • Ah... now it is clearer. Don't ever think of doing it. Unless you would gain hundred of lines of code. – xanatos Jun 03 '15 at 11:46
  • 3
    If you do not want to burn in hell don't use `dynamic`. It's my own opinion. And in 1.5 million os source codes written by me, thereare 2-3 uses of `dynamic`. – General-Doomer Jun 03 '15 at 11:51
  • 1
    If you think you need it, you don't need it. If you know beyond a shadow of a doubt that you do need it, then you still probably don't need it and are just not applying the principles of inheritance correctly. – C Bauer Jun 03 '15 at 11:51
  • 1
    Avoid, avoid, avoid! But... I wrote DynamORM which use this concept alot, and from that experience, I must say that this is mosty a bad thing. Think 10 times before using it. Dynamics are cool when you make some backend and don't know what end developer throws at you, like COM or generic structure/class you must deal with. – dr4cul4 Jun 03 '15 at 15:28
  • @General-Doomer ...could say the same about double negatives? :p – Cool Blue Dec 12 '16 at 09:23
  • @Cool Blue I'm russian, we use double (even triple) negatives in our speech =) – General-Doomer Dec 13 '16 at 10:06

3 Answers3

13

C# has strong typing for a reason. Unless you have a valid reason (such as needing COM interop) to use the dynamic type, you should probably avoid it like the plague, or you'll risk turning compile-time problems into runtime problems. dynamic is powerful, but easy to abuse. Think long and hard about if you really need dynamic typing - if you think there is, there's a chance that you're approaching the problem wrong to begin with, and need to refactor your code.

To specifically answer your question - one potential use case was if you were writing serialisation code and needed to accept a deserialised object, for example a deserialised JSON structure from a web API request. Such methods would need to handle any type given to them, which is a situation in which using dynamic is better than the alternative (ie. a truck-load of reflection).

Another example I can think of would be interoperability with languages specifically on the Dynamic Language Runtime (eg. JavaScript, IronPython, IronRuby, ...), and needed to write a method accepting types from such languages.

From Beginning Visual C# 2012 Programming:

For most C# code that you write, avoid the dynamic keyword. However, if a situation arises where you need to use it, use it and love it - and spare a thought for those poor programmers of the past who didn't have this powerful tool at their disposal.

Tom Galvin
  • 861
  • 7
  • 12
4

Duck-typing is used a lot in C#, you're just unaware of it most of the time. The compiler uses it a lot under the cover, for foreach statements, for Linq, for awaitand for collection initializers. This question details it nicely.

The other way for you to use duck typing is with the dynamic keyword. And let's be franc, you should avoid it as much as possible. But it's very useful to interoperate with dynamic languages/contexts. For instance, suppose you're calling a web service that answers with poorly defined json (so you can't deserialize it easily to a known class). It might be a lot easier for you toparse it as a JObject using json.Net, and use that JObject as a dynamic.

dynamic myParsedJson = JObject.Parse(json);
string theStringImLookingFor = myParsedJson.foo.bar.blah.nicestring;

Another use case is in ASP.net MVC Viewmodels. Having a dynamic viewmodel can be very powerful. The Orchard CMS makes heavy use of it, and even thoug it's a little hard to wrap your head around it at first, it allows very powerful use cases.

COM interop comes to mind as well.

Community
  • 1
  • 1
Falanwe
  • 4,636
  • 22
  • 37
1

Duck Typing:

Please you do this rather than asking who you are.

Example:

Here coding should be simply define and execution. Example, here are the things that I want the following object do something.

    Please("Walk", new Dog());
    Please("Run", new Duck());
    Please("Fly", new Cup());
    Please("Fly", new Bird());
    Please("Fly", new Man());
    Please("Walk", new Man());
    Please("Run", new Man());

This is the result after excuting test.

enter image description here

So, the above objects will do things that we requesting to do only. Additional, I have added the question to ask them answer who they, too. Here is the code in C#.

private void Please(string Action, object Obj)
{
    MethodInfo method = Obj.GetType().GetMethod(Action, Type.EmptyTypes, null);
    if (method != null)
    {
        method.Invoke(Obj, new object[] { });
    }
    else
    {
        Console.WriteLine(string.Format("I can not {0} because {1}", Action, WhoAreYou(Obj)));
    }
}

private string WhoAreYou(object unknown)
{
    string question = "WhoAreYou";
    MethodInfo whoAreYou = unknown.GetType().GetMethod(question, Type.EmptyTypes, null);
    return whoAreYou.Invoke(unknown, new object[] { }).ToString();
}
KHACHORNCHIT
  • 2,222
  • 23
  • 19