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);

我使用第二个构造函数来创建一个 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

在这里分开两件事很重要:

  • Thread对构造函数的调用
  • 创建要传递Thread构造函数的委托

您在这里对后者非常感兴趣 - 之间的区别:

ThreadStart tmp = new ThreadStart(ScanDirectory);

ThreadStart tmp = ScanDirectory;

第二个是方法组转换- 从方法组(方法的名称,如果它是实例方法,可能由实例值限定)到具有兼容签名的委托的隐式转换。

你很少需要第一种形式的“显式”委托创建表达式,因为方法组转换是在 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方法的签名)构造函数以生成适当的委托实例。

隐式调用委托类型的构造函数只是 C# 语言的“语法糖”,而不是 .NET 运行时。

于 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);  

ThreadStart 被隐式创建,因为 ScanDirectory void 与委托具有相同的签名。

在这种情况下,2 完全相同。

请查看 Jon Skeet 在此线程中的答案以获取更多详细信息

于 2012-09-26T06:25:20.303 回答