001: ���using System;
002:
003: namespace GenericMethodBinder
004: {
005: static class ExtensionMethods
006: {
007: public static void StringMethod(this string text)
008: {
009: Console.Write("This the specific extension method for the type string with the text ");
010: Console.WriteLine(text);
011: }
012:
013: public static void GenericMethod<T>(this T value)
014: {
015: Console.Write("This is the generic Extension Method for the type ");
016: Console.Write(typeof(T).ToString());
017: Console.Write(" called with the value ");
018: Console.WriteLine(value.ToString());
019: }
020: }
021:
022: static class MethodBuilder<T>
023: {
024: static string text;
025:
026: static MethodBuilder()
027: {
028: text = "This is the generic Method for the type " + typeof(T).Name + " called with the value ";
029: }
030:
031: public static void Method(T value)
032: {
033: Console.Write(text);
034: Console.WriteLine(value.ToString());
035: }
036: }
037:
038: class Program
039: {
040: static void Main(string[] args)
041: {
042: Console.WriteLine("We are going to play with three method types:");
043: Console.WriteLine(" - Method from a generic type, using the type parameter");
044: Console.WriteLine(" - Generic extension method");
045: Console.WriteLine(" - Specific extension method (which is the same as a regular method)");
046: Console.WriteLine("Direct usage of the methods with the string type, just to show you what happens...");
047: MethodBuilder<string>.Method("toto");
048: "toto".GenericMethod();
049: "toto".StringMethod();
050: Console.WriteLine();
051:
052: Console.WriteLine("Binding the various methods using MethodManager...");
053: MethodManager.Bind<int>(MethodBuilder<int>.Method);
054: MethodManager.Bind<float>(MethodBuilder<float>.Method);
055: MethodManager.Bind<string>(ExtensionMethods.StringMethod);
056: MethodManager.Bind<short>(ExtensionMethods.GenericMethod);
057: MethodManager.Bind<double>(ExtensionMethods.GenericMethod);
058: Console.WriteLine();
059:
060: Console.WriteLine("Using the methods with MethodCaller...");
061: new MethodCaller<int>(42).CallMethod();
062: new MethodCaller<float>(0.5f).CallMethod();
063: new MethodCaller<string>("bla bla bla").CallMethod();
064: new MethodCaller<short>(33).CallMethod();
065: new MethodCaller<double>(666).CallMethod();
066: Console.WriteLine();
067:
068: Console.WriteLine("And finally, we try to use the MethodManager asking for an uninitialized method...");
069: try
070: {
071: new MethodCaller<char>('@').CallMethod();
072: Console.WriteLine("And the call is successful.");
073: }
074: catch (NullReferenceException e)
075: {
076: Console.WriteLine("And the call is unsuccessful.");
077: Console.WriteLine(e.Message);
078: }
079: Console.WriteLine();
080:
081: Console.WriteLine("We could check the bindings before trying to use them, like this: ");
082: TestBinding<int>();
083: TestBinding<string>();
084: TestBinding<float>();
085: TestBinding<decimal>();
086: TestBinding<double>();
087: TestBinding<char>();
088: TestBinding<byte>();
089: TestBinding<short>();
090: Console.WriteLine();
091:
092: Console.WriteLine("That's it.");
093: }
094:
095: static void TestBinding<T>()
096: {
097: Console.WriteLine("The method for type " + typeof(T).Name + " is " + (MethodManager.IsBound<T>() ? string.Empty : "not ") + "bound.");
098: }
099: }
100:
101: delegate void MethodDelegate<T>(T value);
102:
103: static class MethodManager
104: {
105: static class MethodHolder<T>
106: {
107: public static MethodDelegate<T> Method;
108: }
109:
110: public static void Bind<T>(MethodDelegate<T> method)
111: {
112: MethodHolder<T>.Method = method;
113: }
114:
115: public static void CallMethod<T>(T value)
116: {
117: MethodHolder<T>.Method(value);
118: }
119:
120: public static bool IsBound<T>()
121: {
122: return MethodHolder<T>.Method != null;
123: }
124: }
125:
126: public class MethodCaller<T>
127: {
128: T value;
129:
130: public MethodCaller(T value)
131: {
132: this.value = value;
133: }
134:
135: public void CallMethod()
136: {
137: MethodManager.CallMethod(value);
138: }
139: }
140: }