0

问题:

  • 一个 .Net 2.0 类,由代码生成器生成数千个委托字段

    1. 不同的签名
    2. 代表可能会也可能不会返回值
    3. 没有泛型
  • 这些委托可以在运行时快速初始化

    1. 初始化委托很简单但代价高昂
    2. 现在初始化整个批次的成本约为 300 毫秒 - 可以接受,但并不完美
    3. 用户可能会使用不到 10% 的这些委托——如果我们可以只加载这些委托会快得多(不要为不使用的东西付费)

问题:

是否可以使用反射来懒惰地初始化委托字段?在伪代码中:

class Delegates
{
    int FooDelegate(IntPtr p1, float* p2);
    public static FooDelegate Foo;
    // Several thousand more    
    ...

    static Delegate LoadDelegate(string name, Type signature)
    {
        // complex and expensive p/invokes
    }

    static void SetupStubs()
    {
        // Create loader stubs (using reflection because
        // JIT times are prohibitive when done inline)
        foreach (FieldInfo f in typeof(Delegates)
            .GetFields(BindingFlags.Static | BindingFlags.NonPublic))
        {
            // We need to generate a compatible delegate, which:
            // (a) calls LoadDelegate("Foo", typeof(FooDelegate)), and
            // (b) assigns its result to the Foo field (replacing the stub),
            // (c) executes Foo(p1, p2) and returns the result, where 
            // p1 and p2 are the original parameters specified by the user.
            Delegate stub = ...;
            f.SetValue(null, stub);
        }
    }
}

我有一种感觉,可以创建一个执行 (a)、(b) 和 (c) 的存根,但我还没有设法预测如何

理想情况下,代码应该运行 .Net 2.0 和 Mono 2.0,并且不应该使用System.Reflection.Emit。不过,我也对使用 .Net 3.5 或 DynamicMethod 的解决方案感兴趣。

有任何想法吗?:)

4

1 回答 1

1

是的,可以在运行时动态生成存根,但很可能需要 300 毫秒以上的时间——我们正在谈论生成数千个存根。顺便说一句,它需要 DynamicMethods 或 3.5 表达式。

最好的方法是在编译之前生成存根。理想情况下,生成字段的代码生成器也应该生成存根。如果您无法修改现有的代码生成器,您可能需要使用模板引擎,例如 T4。

于 2009-10-21T10:48:44.293 回答