我已经在其目前正在尝试完成的功能完全的示例下重新创建了该类。使用.Net Framework 4.5创建控制台应用程序。在此过程中有很多帮助,我想为其他可能在本文中绊倒的人提供一个有效的例子。一旦一切就绪,我将在* FIXED标记解决方案的顶部。
//*FIXED AND WORKING added benchmark for each variation available only issue is the delegates are slower then MethodInfo.Invoke
using System;
using System.Diagnostics;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace MethodInfoToDelgateInvocation
{
class Program
{
static FindMethods findMethods = new FindMethods();
static DelegateRef delegateRef = new DelegateRef();
static Test test = new Test();
static Stopwatch sw = new Stopwatch();
static void Main(string[] args)
{
findMethods.FindNow(new Test());
sw.Start();
for (int i = 0; i < 10000000; i++)
{
test.HelloWorld(35, "Too Cool", 5.11F);
}
sw.Stop();
Console.WriteLine($"Direct Invoke Time {sw.Elapsed}");
sw.Reset();
sw.Start();
for (int i = 0; i < 10000000; i++)
{
//Test to see if delegateRef will fire off the TestMethod
delegateRef.DelegateReference.Method.Invoke(delegateRef.Class, new object[3] { 35, "Too Cool", 5.11F });
}
sw.Stop();
Console.WriteLine($"Delegate.Method.Invoke Time {sw.Elapsed}");
sw.Reset();
sw.Start();
for (int i = 0; i < 10000000; i++)
{
delegateRef.DelegateReference.DynamicInvoke(new object[3] { 35, "Too Cool", 5.11F });
}
sw.Stop();
Console.WriteLine($"Delegate.DynamicInvoke Time {sw.Elapsed}");
sw.Reset();
sw.Start();
for (int i = 0; i < 10000000; i++)
{
delegateRef.Method.Invoke(delegateRef.Class, new object[3] { 35, "Too Cool", 5.11F });
}
sw.Stop();
Console.WriteLine($"MethodInfo.Invoke Time {sw.Elapsed}");
sw.Reset();
ConsoleKeyInfo key;
do
{
key = Console.ReadKey();
} while (key.Key != ConsoleKey.Escape);
}
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Method)]
public class RSync : Attribute
{
}
public class DelegateRef
{
public int ClassId;
public int Index;
public Delegate DelegateReference;
public MethodInfo Method;
public object Class;
}
public class Test
{
[RSync]
public void HelloWorld(int age, string name, float height)
{
//Console.WriteLine($"Age {age} Name {name} Height {height}");
}
}
public class FindMethods
{
public void FindNow(Test test)
{
const BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance
| BindingFlags.DeclaredOnly | BindingFlags.SetProperty | BindingFlags.GetProperty;
var methods = test.GetType().GetMethods().Where(methodInfo => methodInfo.GetCustomAttributes(typeof(RSync), true).Length > 0).ToList();
var fields = test.GetType().GetFields(flags).Where(fieldInfo => fieldInfo.GetCustomAttributes(typeof(RSync), true).Length > 0).ToList();
if (methods.Count == 0 && fields.Count == 0) return;
foreach (var methodInfo in methods)
{
//shingo's ideology mixed with Adassko expression tree idea
var actionType = Expression.GetActionType(methodInfo.GetParameters().Select(p => p.ParameterType).ToArray());
Console.WriteLine($"Action type {actionType}");
Console.WriteLine($"MethodInfo {methodInfo}");
delegateRef.DelegateReference = Delegate.CreateDelegate(actionType, null, methodInfo);
delegateRef.Method = methodInfo;
delegateRef.Class = test;
}
}
}
}
}
BenchMark(“我在做什么错,应该让代表更快吗?”)
Direct Invoke Time 00:00:00.0405356
Delegate.Method.Invoke Time 00:00:04.3252286
Delegate.DynamicInvoke Time 00:00:17.3568062
MethodInfo.Invoke Time 00:00:03.9669439
非常感谢所有帮助我完成这项工作的人员。(向所有人致谢。)如果可以更有效地调用代表,我很想知道。
Adassko
Alexei Levenkov
Shingo
Tymtam
答案 0 :(得分:1)
我不确定,但是你在追求这样的东西吗?
var fs = new List<Func<string, int>>();
int f1(string s) { return s.Length; };
int f2(string s) { return s.Length * 2; };
fs.Add(f1);
fs.Add(f2);
foreach(var f in fs )
{
Console.WriteLine(f("Is this it?"));
}
输出:
11
22
答案 1 :(得分:1)
public static Type GetDelegateType(Type[] paramTypes, bool noReturnType)
{
if(noReturnType) //Action
{
switch (paramTypes.Length)
{
case 0: return typeof(Action);
case 1: return typeof(Action<>).MakeGenericType(paramTypes);
case 2: return typeof(Action<,>).MakeGenericType(paramTypes);
...
}
}
else //Func
{
switch (paramTypes.Length)
{
case 1: return typeof(Func<>).MakeGenericType(paramTypes);
case 2: return typeof(Func<,>).MakeGenericType(paramTypes);
...
}
}
}