如何使用Delegate.CreateDelegate而不是Func<>定义委托? [英] How to define a delegate using Delegate.CreateDelegate instead of Func<>?

查看:145
本文介绍了如何使用Delegate.CreateDelegate而不是Func<>定义委托?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个方法和两个如下所示的委托。它以这种方式运行。但是我想使用Delegate.CreateInstance。 dx和dy的类型必须为 Func< IEnumerable< Foo>> 。就像下面的FX和FY。它们不能为 Func< int,IEnumerable< Foo>>

I have a method and two delegate like below. It is running in this way. But I want to use Delegate.CreateInstance. The types of the dx and the dy must be Func<IEnumerable<Foo>>. Like below the fx and fy. They must not be Func<int, IEnumerable<Foo>>.

public class Test {
    private IEnumerable<T> CreateItems<T>(int count) where T : class
    {
        for (int i = 0; i < count; i++)
        {
            yield return (T)Activator.CreateInstance(typeof(T), i.ToString());
        }
    }

    public List<T> TestMethod<T>(int i = 1) where T : class
    {
        return CreateItems<T>(i).ToList();
    }

    public void TestRun()
    {
        const int Count = 5;
        Func<IEnumerable<Foo>> fx = () => this.TestMethod<Foo>(Count);
        Func<IEnumerable<Foo>> fy = () => this.TestMethod<Foo>();
        var lfx = fx.Invoke();
        var lfy = fy.Invoke();
        var dx = Delegate.CreateDelegate( ?? );
        var dy = Delegate.CreateDelegate( ?? );
        var ldx = dx.DynamicInvoke();
        var ldy = dy.DynamicInvoke();
    }
}


推荐答案

如果您希望类型为 Func< IEnumerable< Foo>> ,则无法通过 Delegate直接创建 。 CreateDelegate ,因为它们需要两个参数:实例(又名 this )和整数 i 。甚至 fx 中显示的表格也有 i -它恰好是由编译器。如果 TestMethod 不使用参数,则可以通过以下方式完成:

If you want the type to be Func<IEnumerable<Foo>>, then you cannot create that directly via Delegate.CreateDelegate since they require two parameters: the instance (aka this), and the integer i. Even the form shown in fx has an i - it just happens to be supplied by the compiler. If TestMethod didn't take parameters, it could be done via:

var dy = (Func<IEnumerable<Foo>>) Delegate.CreateDelegate(
    typeof(Func<IEnumerable<Foo>>),
    this,
    GetType().GetMethod("TestMethod").MakeGenericMethod(typeof(Foo))
);

要动态执行此操作(部分应用程序),您需要创建一个具有实例( this ),要注入的值( i )和调用的方法 TestMethod< Foo> 包含这些值。 恰好正是编译器为您执行的操作:

To do this (partial application) dynamically, you would need to create a type that has the instance (this), the value to inject (the i), and a method that calls TestMethod<Foo> with those values. Which is exactly what the compiler does for you here:

Func<IEnumerable<Foo>> fx = () => this.TestMethod<Foo>(Count);

这基本上可以创建:

internal class <>_squiggle {
    public Test @this;
    public IEnumerable<Foo> Method() {
        return @this.TestMethod<Foo>(5);
    }
}

和:

var capture = new <>_squiggle { @this = this };
var fx = new Func<IEnumerable<Foo>>(capture.Method);

这篇关于如何使用Delegate.CreateDelegate而不是Func&lt;&gt;定义委托?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆