Daily Knowledge Drop
The term duck typing
refers to the ability to allow for an object to be passed to a method which expects a certain type, even if the object doesn't inherit from the type.
This is more prevalent in dynamic languages and less prevalent in strong type languages, such as C# - however it is still occasionally used.
Duck typing summary
The term duck typing
is explained by the populate phrase:
If it walks like a duck, and quacks like a duck, it must be a duck
How does this relate to code? If a method expects a certain object type as a parameter, and invokes a method on this parameter - with duck typing, a different object with the same method could be used instead of the specified type.
If object type B, looks like object type A, then it must be of type A - and can be used instead of type A.
Valid example
The following C# sample is valid in demonstrating duck typing
, however it WILL NOT COMPILE, but it gives an example of how duck typing works:
public class Duck
{
public int NumberOfWings { get; set; }
public void MakeSound()
{
Console.WriteLine("Quack");
}
}
public class Car
{
public int NumberOfWheels { get; set; }
public void MakeSound()
{
Console.WriteLine("Vroom");
}
}
public class NoiseMaker
{
public void MakeNoise(Duck entity)
{
entity.MakeSound();
}
}
var duck = new Duck();
var car = new Car();
var noiseMaker = new NoiseMaker();
noiseMaker.MakeNoise(duck);
// a strong type lang such as C#
// does not approve of or allow this
noiseMaker.MakeNoise(car);
With duck typing
, the above scenario would be allowed. This is because:
- Both Duck and Car entities have a method called MakeSound(), with the same signature
- The MakeNoise() method only uses the common MakeSound() method, and not either of the fields which are not common (NumberOfWings or NumberOfWheels)
In this setup, according to MakeNoise(), a Car looks like a Duck, and therefor can be used instead.
Invalid example
If the MakeNoise method was altered to also access the NumberOfWings property, then duck typing
would no longer apply:
public class NoiseMaker
{
public void MakeNoise(Duck entity)
{
entity.MakeSound();
duck.NumberOfWings = 2;
}
}
var duck = new Duck();
var car = new Car();
var noiseMaker = new NoiseMaker();
noiseMaker.MakeNoise(duck);
// Not allowed by C#, BUT ALSO not
// allowed according to duck typing
// as Car no longer looks like a Duck
noiseMaker.MakeNoise(car);
With duck typing
, the above scenario would NOT be allowed. This is because:
- Both Duck and Car entities have a method called MakeSound(), with the same signature
- The MakeNoise() method uses the common MakeSound() method, however is also uses the NumberOfWings property, which a Car doesn't have.
In this setup a Car does not look like a Duck, according to MakeNoise()
Valid C# example
The above examples are not valid in C#, as it's a strong-type language which doesn't do a check by similarity, but rather by name/type.
However there are examples of C# using Duck Typing
. A good example of this is GetEnumerator
, outlined in this post
To add the ability to use foreach
on a class, all that is required is that a GetEnumerator method be added to the class, it's not required to be of any type or implement any interface.
If it looks like an enumerator (has a GetEnumerator method), then it is an enumerator!
Notes
Duck typing
is not especially useful or practical in C#, however its a useful general programming concept to know and also to know C# does leverage it occasionally.
References
How Duck Typing Benefits C# Developers
Daily Drop 28: 10-03-2022
At the start of 2022 I set myself the goal of learning one new coding related piece of knowledge a day.
It could be anything - some.NET / C# functionality I wasn't aware of, a design practice, a cool new coding technique, or just something I find interesting. It could be something I knew at one point but had forgotten, or something completely new, which I may or may never actually use.
The Daily Drop is a record of these pieces of knowledge - writing about and summarizing them helps re-enforce the information for myself, as well as potentially helps others learn something new as well.