Reputation: 34188
I heard the word Interface Duck Typing, but do not understand at all what is it? So I read a wiki about this and they said:
In computer programming with object-oriented programming languages, duck typing is a style of typing in which an object's methods and properties determine the valid semantics, rather than its inheritance from a particular class or implementation of an explicit interface. The name of the concept refers to the duck test.
But still could not understand what it. So I saw their program but they use dynamic
keyword to call quack()
& feather()
function of all the classes.
I would request you all please explain in easy way what is Interface Duck Typing and how to implement in C# v2.0 because there is no dynamic
keyword.
using System;
namespace DuckTyping
{
public class Duck
{
public void Quack()
{
Console.WriteLine("Quaaaaaack!");
}
public void Feathers()
{
Console.WriteLine("The duck has white and gray feathers.");
}
}
public class Person
{
public void Quack()
{
Console.WriteLine("The person imitates a duck.");
}
public void Feathers()
{
Console.WriteLine("The person takes a feather from the ground and shows it.");
}
}
internal class Program
{
private static void InTheForest(dynamic duck)
{
duck.Quack();
duck.Feathers();
}
private static void Game()
{
Duck donald = new Duck();
Person john = new Person();
InTheForest(donald);
InTheForest(john);
}
private static void Main()
{
Game();
}
}
}
Upvotes: 34
Views: 20185
Reputation: 19
You can use Events and exploit C# best suitable overload functions.
Hopefully, it will be useful :)
To get something Like a duck typing (.Net 4.+):
using System.Collections;
using System.Collections.Generic;
public interface IAny
{
void InvokeGetterEvent();
}
public class AnyValueTypeDuck<T, V> : IAny
where V : AnyValueTypeDuck<T, V>
{
public static event System.Action<V> GetterEvent;
public T Data;
public void InvokeGetterEvent()
{
GetterEvent.Invoke((V)this);
}
}
// Then create some concrete classes:
// Example :
public class LifeConcreteProperty : AnyValueTypeDuck<int, LifeConcreteProperty>
{
}
public class ManaConcreteProperty : AnyValueTypeDuck<float, ManaConcreteProperty>
{
}
// Now to finally use it :
public class UserClass
{
List<IAny> allDuckTypes = new List<IAny>();
public void GetDucketTypeClass(IAny anyDuckObject)
{
LifeConcreteProperty.GetterEvent += GetDucketType;
ManaConcreteProperty.GetterEvent += GetDucketType;
anyDuckObject.InvokeGetterEvent();
// it will propagate to event and will invoke
// best suitable overload method (GetDucketType)
LifeConcreteProperty.GetterEvent -= GetDucketType;
ManaConcreteProperty.GetterEvent -= GetDucketType;
}
public void GetDucketType(LifeConcreteProperty originalClass)
{
// Your efforts go here
int value = originalClass.Data;
}
public void GetDucketType(ManaConcreteProperty originalClass)
{
// Your efforts go here
float value = originalClass.Data;
}
}
Upvotes: 0
Reputation: 2320
About Duck Typing:
We don't need to know what the object is, but we just want to let the object do something if it can do.
Example:
Example, if here are the things that we want the following objects do.
PleaseWalk(new Dog());
PleaseRun(new Duck());
PleaseWalk(new Cup());
PleaseFly(new Man());
PleaseFly(new Bird());
And, here is the result after we request the above objects do the things.
So, we don't need to check what the object is, but we can let it do something enough. Here is the code that I have written in C#.
private void PleaseWalk(object obj)
{
string Method = "Walk";
MethodInfo walkMethod = obj.GetType().GetMethod(Method, Type.EmptyTypes, null);
if (walkMethod != null)
{
walkMethod.Invoke(obj, new object[] { });
}
else
{
Console.WriteLine(string.Format("I can not {0} because {1}", Method, WhoAreYou(obj)));
}
}
private string WhoAreYou(object unknown)
{
MethodInfo whoAreYou = unknown.GetType().GetMethod("WhoAreYou", Type.EmptyTypes, null);
return whoAreYou.Invoke(unknown, new object[] { }).ToString();
}
Upvotes: 5
Reputation: 144136
C# has a nominal type system, so the compatibility of types is done based on their names. In your example you have two classes with a Quack
method, however there is no way to write a method which can take instances of these two classes and invoke their Quack
method.
In C# 2, the solution would be to introduce an interface and have both classes implement it:
public interface IQuack
{
void Quack();
}
public class Duck : IQuack { }
public class Human : IQuack { }
now you can create a method which take an IQuack
instance and can call Human.Quack
and Duck.Quack
through it. In C#, methods are resolved 'early' at compile time, so you need to create a named type which supports the operations the method need so the compilation can succeed. Note there is still a runtime element to calling these methods, since the real implementation of IQuack.Quack
needs to be resolved at runtime depending on the real type of the argument.
In a duck-typing system, no attempt is made to validate that a method exists before runtime. All that is required is that a given object supports the operation in that it has the right name and takes the required number of parameters (none in this case), hence the 'if it quacks like a duck' expression.
Duck typing in C# 2 can only be done using reflection, in this case you would accept an object
argument and look for the required methods yourself:
public static void MakeQuack(object duck)
{
MethodInfo quackMethod = duck.GetType().GetMethod("Quack", Type.EmptyTypes, null);
if (quackMethod!=null)
{
quackMethod.Invoke(duck, new object[] { });
}
else
{
throw new ArgumentException("No Quack() method found on target");
}
}
C#4 makes this much simpler with dynamic
:
public static void MakeQuack(dynamic duck)
{
duck.Quack();
}
Upvotes: 30
Reputation: 5507
It would say it is a way of coding where the you tell the compiler:
"Hey trust me I know what methods and properties this object supports. You don't need to check them for me whilst I code."
Once you run your app the compiler will go: "Ok lets see if I could trust you. Let me do some runtime binding."
If you then made a mistake, such as using an unsupported method, the compiler will shout: "Hey man, this is not supported! Check my RuntimeBinderException!"
Upvotes: 12
Reputation: 4958
Duck 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.
Please refer this to get an idea about Duck Typing
http://haacked.com/archive/2007/08/19/why-duck-typing-matters-to-c-developers.aspx/
Upvotes: 10