8

私は、2 つの関数をパラメーターとして取り、新しい合成関数を返す関数を使用しています。

public static Action<T> Compose<T>(Action<T> first, Action second)
{
    return new Action<T>(arg =>
    {
        first(arg);
        second();
    });
}

(実際のオブジェクトTではなく) 静的関数またはメンバー関数を送信するときに、 を指定しないと、コンパイラが文句を言うことに気付きました。Action<T>

static void Main(string[] args)
{
    // compiler error here
    var composed = Compose(Test, () => Console.WriteLine(" world"));
    composed("hello");

    Console.ReadLine();
}

public static void Test(string arg)
{
    Console.Write(arg);
}

エラーメッセージ:

メソッド 'ConsoleTest.Program.Compose(System.Action, System.Action)' の引数は、使用法から推測できません。型引数を明示的に指定してみてください。

私の質問: 型引数をここで推論できないのはなぜですか? の署名はTestコンパイル時にわかりますね。Testの代わりに、その署名があいまいになる可能性のある関数は本当にありますか?

脚注: (この質問に記載されているように) tonew Action<string>(Test)の代わりに単に送信できることはわかっています。私の質問は、「どうすればこれを行うことができるか」ではなく「なぜ」です。TestCompose

4

2 に答える 2

0

それは共分散と関係があるかもしれません。の引数の型Testはわかっていますが、より具体的な型のデリゲートを作成したい場合があります。

public class BaseClass { }
public class DerivedClass : BaseClass { }

static class Program
{
    static void Main(string[] args)
    {
        var composed = Compose<DerivedClass>(Test, () => Console.WriteLine(" world"));
        composed(new DerivedClass());

        Console.ReadLine();
    }

    public static void Test(BaseClass arg)
    {
        Console.Write(arg);
    }
}
于 2013-09-25T21:33:08.213 に答える