6

重複の可能性:
new Thread(void Target()) と new Thread(new ThreadStart(void Target())) の違いは何ですか?

Thread クラスについてちょっとした質問があります。このクラスには 4 つのコンストラクターがあります。

public Thread(ParameterizedThreadStart start);
public Thread(ThreadStart start);
public Thread(ParameterizedThreadStart start, int maxStackSize);
public Thread(ThreadStart start, int maxStackSize);

2 番目のコンストラクターを使用して Thread オブジェクトを作成します。

Thread thread = new Thread(new ThreadStart(ScanDirectory));

ただし、上で説明したコンストラクターを使用せずに、このオブジェクトを作成する方法を使用できます。

Thread thread = new Thread(ScanDirectory);

この場合、ScanDirectory は void メソッドであり、ThreadStart または ParameterizedThreadStart ではありませんが、Thread クラスは引き続きこのコンストラクターを受け入れます。なんで?これは .NET の機能だと思いますが、どのように実装されているかわかりません。

注: ScanDirectory は void メソッドです。

4

4 に答える 4

9

ここで 2 つのことを区別することが重要です。

  • Threadコンストラクターの呼び出し
  • コンストラクターに渡すデリゲートの作成Thread

ここで後者に本当に興味があります-次の違い:

ThreadStart tmp = new ThreadStart(ScanDirectory);

ThreadStart tmp = ScanDirectory;

これらの 2 つ目は、メソッド グループの変換です。メソッド グループ(メソッドの名前。インスタンス メソッドの場合は、インスタンス値によって修飾される可能性があります) から、互換性のあるシグネチャを持つデリゲートへの暗黙的な変換です。

メソッド グループの変換が C# 2 で導入されたため、最初の形式の "明示的な" デリゲート作成式が必要になることはほとんどありません。残念ながら、多くの開発者がメソッド グループの変換を認識していないため、まだそれを使用している多くのコードが表示されます。 IIRC の Visual Studio デザイナーは、イベント ハンドラーのサブスクリプションにそのフォームを引き続き使用します。

本当に必要になるのは、メソッド グループの変換があいまいになったときだけです。例えば:

static void Main()
{
    // Valid: uses parameterless overload
    new Thread(new ThreadStart(Foo));

    // Valid: uses parameterized overload
    new Thread(new ParameterizedThreadStart(Foo));

    // Invalid, as there are two valid constructor overloads
    new Thread(Foo);
}

static void Foo()
{
}

static void Foo(object state)
{
}
于 2012-09-26T06:28:57.927 に答える
2

これ:

Thread thread = new Thread(ScanDirectory)

引き続きThreadコンストラクターを呼び出し、暗黙的にコンストラクターを呼び出してThreadStart(またはParameterizedThreadStart、メソッドのシグニチャーによってはScanDirectory)、適切なデリゲートインスタンスを作成します。

デリゲート型のコンストラクターの暗黙的な呼び出しは、.NETランタイムではなく、C#言語の単なる「シンタックスシュガー」です。

于 2012-09-26T06:22:21.253 に答える
2

実際、voidメソッドを渡すときは、最初のコンストラクターを使用しています。ドキュメントから引用した例を次に示します。

// To start a thread using an instance method for the thread  
// procedure, use the instance variable and method name when  
// you create the ParameterizedThreadStart delegate. C# infers  
// the appropriate delegate creation syntax: 
//    new ParameterizedThreadStart(w.DoMoreWork) 
//
Work w = new Work();
newThread = new Thread(w.DoMoreWork);
于 2012-09-26T06:23:47.853 に答える
0

ここ:

Thread thread = new Thread(new ThreadStart(ScanDirectory)); 

ScanDirectory void をコンストラクターに渡すことにより、ThreadStart デリゲートを明示的に作成しています。

ここ:

Thread thread = new Thread(ScanDirectory);  

ScanDirectory void はデリゲートと同じ署名を持っているため、ThreadStart は暗黙的に作成されています。

この場合、2 つはまったく同じです。

詳細については、このスレッドのJon Skeetの回答をご覧ください

于 2012-09-26T06:25:20.303 に答える