2

以下のようなメソッドと2つのデリゲートがあります。このように実行されています。しかし、Delegate.CreateInstanceを使用したいと思います。dxとdyのタイプはである必要がありますFunc<IEnumerable<Foo>>。fxとfyの下のように。であってはなりません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();
    }
}
4

2 に答える 2

2

それ無理。署名付きのインスタンスメソッドを直接適合A F(X x)させる方法はありません。Func<A>

メソッドの最初のパラメーターをデリゲートに直接バインドすることは可能ですが、追加のパラメーターをバインドすることはできません。あなたの場合、インスタンスthisはその最初のパラメータであり、の値をバインドすることはできませんi

あなたの誤解は、デフォルト値のパラメータがどのように機能するかということだと思います。これらは、呼び出し元が入力する必要のあるパラメーターです。それは、C#コンパイラがあなたに代わってそれを行うということだけです。

正しい署名を持つある種のラッパーが必要になります。それはラムダ、または他のヘルパーメソッドである可能性があります。あなたの場合TestMethod、デフォルトのパラメータを使用する代わりに、メソッドをオーバーロードします。

于 2012-10-19T12:23:35.900 に答える
2

タイプをにしたい場合は、インスタンス(別名)と整数の2つのパラメーターが必要なため、を介して直接Func<IEnumerable<Foo>>作成することはできません。に示されいる形式でさえ-があります-それはたまたまコンパイラによって提供されます。パラメータを取得しなかった場合は、次の方法で実行できます。Delegate.CreateDelegatethisifx iTestMethod

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

これ(部分適用)を動的に行うには、インスタンス(this)、注入する値( )、およびそれらの値を使用して呼び出すiメソッドを持つ型を作成する必要があります。これはまさにコンパイラがここであなたのために行うことです: TestMethod<Foo>

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);
于 2012-10-19T12:25:26.860 に答える