8

私は本当に単純なコードを持っています:

static void Main(string[] args)
{
    var task = Task.Factory.StartNew(GetInt);

    var task2 = Task.Factory.StartNew(
        () =>
        {
            return GetInt();
        });
}

static int GetInt()
{
    return 64;
}

最初のタスクでコンパイラ エラーが発生するのはなぜですか? メソッドのシグネチャ (パラメーターなし、戻り値の型はint) は同じですよね?

私は解決策を知っています(これは非常に簡単ですvar task = Task.Factory.StartNew<int>(GetInt);:)が、上記のコードの問題を知りたいです。

4

6 に答える 6

3

コンパイラは、これら 2 つのオーバーロードのどちらを使用するかを決定できないためです。

StartNew(Action)
StartNew<TResult>(Func<TResult>)

その理由は、戻り値の型が C# のオーバーロード解決の一部ではないため (戻り値の型だけが異なる 2 つのオーバーロードを持つことができないのと同じように)、コンパイラはGetIntanActionか aかを決定できないためFunc<T>です。呼び出してジェネリック バージョンを強制的に使用するStartNew<int>(GetInt)と、必要な情報が提供されます。

于 2012-04-05T19:13:11.303 に答える
3

メソッドのシグネチャが同じであるため、あいまいな呼び出しエラーが発生します。戻り値は署名の一部ではありません。

明示的な戻り値の型を指定しないため、コンパイラはどちらを取るべきかわかりません。

C# のメソッド シグネチャ

于 2012-04-05T19:01:25.817 に答える
2

記録のために、これを行うためのさらに2つの方法があります(コンパイルします):

var task3 = Task.Factory.StartNew((Func<int>)GetInt);
var task4 = Task.Factory.StartNew(() => GetInt());
于 2012-04-05T19:11:22.700 に答える
1

例外を表示するのに役立ちます: 「呼び出しは、次のメソッドまたはプロパティの間であいまいです: 'System.Threading.Tasks.TaskFactory.StartNew(System.Action)' および 'System.Threading.Tasks.TaskFactory.StartNew(System.Func) )'"

調べてみると、次の 2 つの方法が考えられます。

public Task<TResult> StartNew<TResult>(Func<TResult> function);
public Task StartNew(Action action);

を追加する<int>か、 aFunc<int>を指定すると、強制的に最初の署名が取得されます。それがなければ、コードはあいまいです。

于 2012-04-05T19:06:23.287 に答える
0

StartNew メソッドは Action (void を返す) または Func (何かを返す) のいずれかを受け取り、直接のデリゲートではなく、さまざまなオーバーロードを使用するため、コンパイル エラーが発生します。

于 2012-04-05T18:58:50.453 に答える
0

他の人が述べたように、GetInt を関数として StartNew に渡すか、ジェネリック型を指定して StartNew から値を返すことを指定する必要があります。そうしないと、コンパイラは、作成しようとしているタスクの種類を認識できません....あいまいです。

static void Main(string[] args)
{
    var task = Task.Factory.StartNew<int>(GetInt);

    var task2 = Task.Factory.StartNew(
        () =>
        {
            return GetInt();
        });
}

static int GetInt()
{
    return 64;
}
于 2012-04-05T19:08:35.177 に答える