17章最后一节 谈到CreateDelegate方法和DynamicInvoke方法
下面是书上提供的例子(有改动):
using System.IO;
using System.Reflection;
namespace DelegateReflection
{
internal delegate Object TwoInt32s(Int32 n1, Int32 n2);
internal delegate Object OneString(String s1);
class Program
{
static void Main(string[] args)
{
//DelegateReflection.TwoInt32s 全称namespace.[DelegateName],否则报错
//DelegateReflection.OneString
string[] strArray = new string[] { "TwoInt32s", "Add", "123", "100" };
Go(strArray);
Console.ReadKey();
}
public static void Go(String[] args)
{
if (args.Length < 2)
{
String fileName = Path.GetFileNameWithoutExtension(Assembly.GetEntryAssembly().Location);
String usage =
@"Usage:" +
"{0}{1} delType methodName [Arg1] [Arg2]" +
"{0} where delType must be TwoInt32s or OneString" +
"{0} if delType is TwoInt32s, methodName must be Add or Subtract" +
"{0} if delType is OneString, methodName must be NumChars or Reverse" +
"{0}" +
"{0}Examples:" +
"{0} {1} TwoInt32s Add 123 321" +
"{0} {1} TwoInt32s Subtract 123 321" +
"{0} {1} OneString NumChars \"Hello there\"" +
"{0} {1} OneString Reverse \"Hello there\"";
Console.WriteLine(usage, Environment.NewLine, fileName);
return;
}
//Type t = Type.GetType("TwoInt32s");
//Console.WriteLine(t.FullName);
// Convert the delType argument to a delegate type
Type delType = Type.GetType(args[0]);
if (delType == null)
{
Console.WriteLine("Invalid delType argument: " + args[0]);
return;
}
Delegate d;
try
{
// Convert the Arg1 argument to a method
MethodInfo mi = typeof(Program).GetMethod(args[1], BindingFlags.NonPublic | BindingFlags.Static);
// Create a delegate object that wraps the static method
d = Delegate.CreateDelegate(delType, mi);
}
catch (ArgumentException)
{
Console.WriteLine("Invalid methodName argument: " + args[1]);
return;
}
// Create an array that that will contain just the arguments
// to pass to the method via the delegate object
Object[] callbackArgs = new Object[args.Length - 2];
if (d.GetType() == typeof(TwoInt32s))
{
try
{
// Convert the String arguments to Int32 arguments
for (Int32 a = 2; a < args.Length; a++)
callbackArgs[a - 2] = Int32.Parse(args[a]);
}
catch (FormatException)
{
Console.WriteLine("Parameters must be integers.");
return;
}
}
if (d.GetType() == typeof(OneString))
{
// Just copy the String argument
Array.Copy(args, 2, callbackArgs, 0, callbackArgs.Length);
}
try
{
// Invoke the delegate and show the result
Object result = d.DynamicInvoke(callbackArgs);
Console.WriteLine("Result = " + result);
}
catch (TargetParameterCountException)
{
Console.WriteLine("Incorrect number of parameters specified.");
}
}
// This callback method takes 2 Int32 arguments
private static Object Add(Int32 n1, Int32 n2)
{
return n1 + n2;
}
// This callback method takes 2 Int32 arguments
private static Object Subtract(Int32 n1, Int32 n2)
{
return n1 - n2;
}
// This callback method takes 1 String argument
private static Object NumChars(String s1)
{
return s1.Length;
}
// This callback method takes 1 String argument
private static Object Reverse(String s1)
{
Char[] chars = s1.ToCharArray();
Array.Reverse(chars);
return new String(chars);
}
}
}