在我的程序中,我们分割了大量需要在四个线程中查看的数据。
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对象,我无法弄清楚如何获得我需要完成的任何对象。
我的问题:匿名代表是如何工作的?他们编译到什么?最后,我必须在没有匿名代表的情况下让这个工作,但我不知道从哪里开始。
感谢您的帮助,
导引头
答案 0 :(得分:7)
您有两种选择:
new ThreadStart(delegate { ... })
没有括号的匿名方法(delegate { ... }
)具有隐式参数列表。编译器将为其提供匹配其所使用的委托所需的任何参数。 (您的代码无法查看参数)
在编写不使用其参数的匿名事件处理程序时,这非常有用;它可以帮助您免于键入delegate(object sender, EventArgs e) { ... }
。
但是,在调用Thread
构造函数时,有两种不同的重载需要两种代理。
编译器无法知道您尝试创建哪种委托类型,因为您没有指定参数列表。
答案 1 :(得分: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); });
但我的建议是LART StyleCop的作者引入这个荒谬的规则。
答案 2 :(得分:2)
您可以使用lambda表达式而不是delegate
关键字:
Thread one = new Thread(() => NewMethod(recordsSplitIntoQuarters[0], param2, param3, param4, param5));