���using System;
namespace GenericMethodBinder
{
static class ExtensionMethods
{
public static void StringMethod(this string text)
{
Console.Write("This the specific extension method for the type string with the text ");
Console.WriteLine(text);
}
public static void GenericMethod<T>(this T value)
{
Console.Write("This is the generic Extension Method for the type ");
Console.Write(typeof(T).ToString());
Console.Write(" called with the value ");
Console.WriteLine(value.ToString());
}
}
static class MethodBuilder<T>
{
static string text;
static MethodBuilder()
{
text = "This is the generic Method for the type " + typeof(T).Name + " called with the value ";
}
public static void Method(T value)
{
Console.Write(text);
Console.WriteLine(value.ToString());
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("We are going to play with three method types:");
Console.WriteLine(" - Method from a generic type, using the type parameter");
Console.WriteLine(" - Generic extension method");
Console.WriteLine(" - Specific extension method (which is the same as a regular method)");
Console.WriteLine("Direct usage of the methods with the string type, just to show you what happens...");
MethodBuilder<string>.Method("toto");
"toto".GenericMethod();
"toto".StringMethod();
Console.WriteLine();
Console.WriteLine("Binding the various methods using MethodManager...");
MethodManager.Bind<int>(MethodBuilder<int>.Method);
MethodManager.Bind<float>(MethodBuilder<float>.Method);
MethodManager.Bind<string>(ExtensionMethods.StringMethod);
MethodManager.Bind<short>(ExtensionMethods.GenericMethod);
MethodManager.Bind<double>(ExtensionMethods.GenericMethod);
Console.WriteLine();
Console.WriteLine("Using the methods with MethodCaller...");
new MethodCaller<int>(42).CallMethod();
new MethodCaller<float>(0.5f).CallMethod();
new MethodCaller<string>("bla bla bla").CallMethod();
new MethodCaller<short>(33).CallMethod();
new MethodCaller<double>(666).CallMethod();
Console.WriteLine();
Console.WriteLine("And finally, we try to use the MethodManager asking for an uninitialized method...");
try
{
new MethodCaller<char>('@').CallMethod();
Console.WriteLine("And the call is successful.");
}
catch (NullReferenceException e)
{
Console.WriteLine("And the call is unsuccessful.");
Console.WriteLine(e.Message);
}
Console.WriteLine();
Console.WriteLine("We could check the bindings before trying to use them, like this: ");
TestBinding<int>();
TestBinding<string>();
TestBinding<float>();
TestBinding<decimal>();
TestBinding<double>();
TestBinding<char>();
TestBinding<byte>();
TestBinding<short>();
Console.WriteLine();
Console.WriteLine("That's it.");
}
static void TestBinding<T>()
{
Console.WriteLine("The method for type " + typeof(T).Name + " is " + (MethodManager.IsBound<T>() ? string.Empty : "not ") + "bound.");
}
}
delegate void MethodDelegate<T>(T value);
static class MethodManager
{
static class MethodHolder<T>
{
public static MethodDelegate<T> Method;
}
public static void Bind<T>(MethodDelegate<T> method)
{
MethodHolder<T>.Method = method;
}
public static void CallMethod<T>(T value)
{
MethodHolder<T>.Method(value);
}
public static bool IsBound<T>()
{
return MethodHolder<T>.Method != null;
}
}
public class MethodCaller<T>
{
T value;
public MethodCaller(T value)
{
this.value = value;
}
public void CallMethod()
{
MethodManager.CallMethod(value);
}
}
}