为什么新的Thread()接受方法名称,即使没有构造函数重载似乎允许这样做?

可能重复:
新的Thread(void Target())和新的Thread(新的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类仍然接受此构造函数。 为什么? 我认为这是一个.NETfunction,但我不知道它是如何实现的。

注意: ScanDirectory是一种void方法。

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

  • Thread构造函数的调用
  • 创建一个传递Thread构造函数的委托

真的对后者感兴趣 – 两者之间的区别:

 ThreadStart tmp = new ThreadStart(ScanDirectory); 

 ThreadStart tmp = ScanDirectory; 

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

您很少需要第一个表单的“显式”委托创建表达式,因为方法组转换是在C#2中引入的。您会看到许多仍然使用它的代码,因为很多开发人员都不知道方法组转换,不幸的是 – 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) { } 

这个:

 Thread thread = new Thread(ScanDirectory) 

仍然调用Thread构造函数,并隐式调用ThreadStart (或ParameterizedThreadStart ,具体取决于ScanDirectory方法的签名)构造函数来制作适当的委托实例。

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

实际上当你传递一个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); 

这里:

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

您通过将ScanDirectory void传递给构造函数来显式创建ThreadStart委托

这里:

 Thread thread = new Thread(ScanDirectory); 

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

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

有关更多详细信息,请查看Jon Skeet在此主题中的答案