6

在我的程序中,我们拆分了大量需要在四个线程中查看的数据。

Thread one = new Thread(delegate() { NewMethod(recordsSplitIntoQuarters[0], param2, param3, param4, param5); });
Thread two = new Thread(delegate() { NewMethod(recordsSplitIntoQuarters[1], param2, param3, param4, param5); });
Thread three = new Thread(delegate() { NewMethod(recordsSplitIntoQuarters[2], param2, param3, param4, param5); });
Thread four= new Thread(delegate() { NewMethod(recordsSplitIntoQuarters[3], param2, param3, param4, param5); });

我们的编码标准要求我们符合 StyleCop,事实上,StyleCop 要求以下:

SA1410:从匿名方法中删除括号,因为委托的参数列表为空。

这样做会给我这个编译器错误:

以下方法或属性之间的调用不明确:“System.Threading.Thread.Thread(System.Threading.ParameterizedThreadStart)”和“System.Threading.Thread.Thread(System.Threading.ThreadStart)”

我已经研究了 ThreadStart 和 ParameterizedThreadStart 对象,但我无法弄清楚如何使用这些对象中的任何一个来完成我需要完成的工作。

我的问题:匿名代表如何工作?他们编译成什么?最后,我将不得不在没有匿名代表的情况下完成这项工作,但我不知道从哪里开始。

谢谢您的帮助,

寻找者

4

3 回答 3

7

你有两个选择:

  • 忽略 StyleCop 警告(推荐)
  • 将其更改为new ThreadStart(delegate { ... })

解释:

不带括号 ( ) 的匿名方法delegate { ... }具有隐式参数列表。编译器将为它提供任何所需的参数来匹配它被用作的委托。(您的代码看不到参数)
这在编写不使用参数的匿名事件处理程序时非常有用;它使您免于打字delegate(object sender, EventArgs e) { ... }

但是,在调用Thread构造函数时,有两种不同的重载采用两种委托。
编译器无法知道您尝试创建的委托类型,因为您没有指定参数列表。

于 2010-11-30T20:50:21.360 回答
5

StyleCop 是愚蠢的。

StyleCop 暗示这两种语法具有相同的含义。 这是完全错误的。 从委托中省略括号并不意味着“这不需要参数”。这意味着“为我填写任何参数,因为无论如何我都不会使用它们。”

由于有两个不同的签名Thread:.ctor可用,每个都采用不同的委托类型,编译器无法知道选择哪一个,因为任何一个都可以。添加括号会强制编译器选择ThreadStart变体,因为它是唯一具有与您的匿名方法兼容的委托类型的签名。

如果您想让 StyleCop 满意编译您的代码,这是一种选择:

Thread one = new Thread(new ThreadStart(delegate { NewMethod(recordsSplitIntoQuarters[0], param2, param3, param4, param5); }));

这是另一个:

Thread one = new Thread((ThreadStart) delegate { NewMethod(recordsSplitIntoQuarters[0], param2, param3, param4, param5); });

但我的建议是向 StyleCop 的作者 LART 介绍这条荒谬的规则。

于 2010-11-30T20:52:34.647 回答
3

您可以使用 lambda 表达式代替delegate关键字:

Thread one = new Thread(() => NewMethod(recordsSplitIntoQuarters[0], param2, param3, param4, param5));
于 2010-11-30T20:53:44.823 回答