Skip to content

Instantly share code, notes, and snippets.

@opavlyshak
Created December 18, 2012 12:24
Show Gist options
  • Save opavlyshak/4327546 to your computer and use it in GitHub Desktop.
Save opavlyshak/4327546 to your computer and use it in GitHub Desktop.
using System;
// Example from acticle by Eric Lippert http://blogs.msdn.com/b/ericlippert/archive/2011/03/17/implementing-the-virtual-method-pattern-in-c-part-one.aspx
namespace VirtualMethodsImplementation
{
internal sealed class VTable
{
public readonly Func<Animal, string> Complain;
public readonly Func<Animal, string> MakeNoise;
public VTable(Func<Animal, string> complain, Func<Animal, string> makeNoise)
{
Complain = complain;
MakeNoise = makeNoise;
}
}
internal abstract class Animal
{
public VTable VTable;
public static string MakeNoise_(Animal _this)
{
return "";
}
}
internal class Giraffe : Animal
{
private static readonly VTable GiraffeVTable = new VTable(Giraffe.Complain_, Animal.MakeNoise_);
public bool SoreThroat { get; set; }
public static string Complain_(Animal _this)
{
return (_this as Giraffe).SoreThroat ? "What a pain in the neck!" : "No complaints today.";
}
public static Giraffe Create()
{
Giraffe giraffe = new Giraffe();
giraffe.VTable = Giraffe.GiraffeVTable;
return giraffe;
}
}
internal class Cat : Animal
{
private static readonly VTable CatVTable = new VTable(Cat.Complain_, Cat.MakeNoise_);
public bool Hungry { get; set; }
public static string Complain_(Animal _this)
{
return (_this as Cat).Hungry ? "GIVE ME THAT TUNA!" : "I HATE YOU ALL!";
}
public static string MakeNoise_(Animal _this)
{
return "MEOW MEOW MEOW MEOW MEOW MEOW";
}
public static Cat Create()
{
Cat cat = new Cat();
cat.VTable = Cat.CatVTable;
return cat;
}
}
internal class Dog : Animal
{
private static readonly VTable DogVTable = new VTable(Dog.Complain_, Animal.MakeNoise_);
public bool Small { get; set; }
public static string Complain_(Animal _this)
{
return "Our regressive state tax code is... SQUIRREL!";
}
public static string MakeNoise_(Dog _this)
{
return _this.Small ? "yip" : "WOOF";
}
public static Dog Create()
{
Dog dog = new Dog();
dog.VTable = Dog.DogVTable;
return dog;
}
}
internal static class Program
{
public static void Main(string[] args)
{
string s;
Animal animal = Giraffe.Create();
s = animal.VTable.Complain(animal); // no complaints
s = animal.VTable.MakeNoise(animal); // no noise
animal = Cat.Create();
s = animal.VTable.Complain(animal); // I hate you
s = animal.VTable.MakeNoise(animal); // meow!
Dog dog = Dog.Create();
animal = dog;
s = animal.VTable.Complain(animal); // squirrel!
s = animal.VTable.MakeNoise(animal); // no noise
s = Dog.MakeNoise_(dog); // yip!
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment