为什么新的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在此主题中的答案