Using dynamic keyword to resolve double dispatch, overloaded methods using derived types at compile time.
using System;
using System.Collections.Generic;
using System.Reflection;
namespace OverloadedMethod
{
class Program
{
static void Main(string[] args)
{
var processor = new Processor();
var shapes = new List<Shape> {new Circle(), new Triangle()};
foreach (var shape in shapes)
{
// option 1
processor.GetType()
.GetMethod("Execute",
BindingFlags.Instance | BindingFlags.NonPublic,
null,
new[] { shape.GetType() },
null)
.Invoke(processor,
new object[] { shape });
// or option 2 (requires known definition of all drived types and a line per type)
if (shape is Circle) processor.Execute(shape as Circle);
else if (shape is Triangle) processor.Execute(shape as Triangle);
// option 3... BOOM!!!! Works a treat :)
processor.Execute(shape as dynamic);
}
}
}
class Shape { }
class Circle : Shape
{
public int Circumference { get { return 10; } }
}
class Triangle : Shape
{
public int HypotenuseLength { get { return 20; } }
}
class Processor
{
internal void Execute(Circle circle)
{
Console.WriteLine("Executing with a Circle with circumference {0}!", circle.Circumference);
}
internal void Execute(Triangle triangle)
{
Console.WriteLine("Executing with a Triangle hypotenuse length of {0}!", triangle.HypotenuseLength);
}
}
}
Source: https://github.com/stevenh77/OverloadedMethod/
So what about this, using an extension method? Apparently Circle doesn’t have a definition for Execute…
Source: https://github.com/stevenh77/OverloadedMethodExtensions/
using System;
using System.Collections.Generic;
namespace OverloadedMethod
{
class Program
{
static void Main(string[] args)
{
var shapes = new List<Shape> {new Circle(), new Triangle()};
foreach (var shape in shapes)
{
// option 4: so what about this....?
// (shape as dynamic).Execute(); // doesn't work
ExtensionMethods.Execute(shape as dynamic); // this works!
}
}
}
class Shape { }
class Circle : Shape
{
public int Circumference { get { return 10; } }
}
class Triangle : Shape
{
public int HypotenuseLength { get { return 20; } }
}
static class ExtensionMethods
{
public static void Execute(this Circle circle)
{
Console.WriteLine("Executing with a Circle with circumference {0}!", circle.Circumference);
}
public static void Execute(this Triangle triangle)
{
Console.WriteLine("Executing with a Triangle hypotenuse length of {0}!", triangle.HypotenuseLength);
}
}
}
No comments:
Post a Comment