Roo*_*ian 9 c# multithreading delegates action
两者都是委托并具有相同的签名,但我不能将Action用作ThreadStart.
为什么?
Action doIt;
doIt = () => MyMethod("test");
Thread t;
t = new Thread(doIt);
t.Start();
Run Code Online (Sandbox Code Playgroud)
但这似乎有效:
Thread t;
t = new Thread(() => MyMethod("test"));
t.Start();
Run Code Online (Sandbox Code Playgroud)
Eri*_*ert 21
正如其他人所指出的那样,问题在于委托类型不是"结构性的".也就是说,它们没有基于其"结构"的等价.
现在,对于某些类型来说,这可能是件好事.如果你有
struct MyRectangle { int x; int y; int width; int height; ... }
Run Code Online (Sandbox Code Playgroud)
和
struct YourRectangle { int x1; int y1; int x2; int y2; ... }
Run Code Online (Sandbox Code Playgroud)
很明显,允许将MyRectangle的实例分配给YourRectangle的变量是错误的,因为它们都包含四个整数.整数的语义不同,因此类型不等同.
从理论上讲,对代表来说也是如此.你可以有
delegate int Pure(string x);
delegate int Func(string x);
Run Code Online (Sandbox Code Playgroud)
其中"纯"函数是没有副作用的函数,并且在给定相同输入的情况下输出相同.由于每个Pure在逻辑上都是Func,但每个Func不一定是Pure,因此它们之间不应该有结构类型.
在实践中,类型系统当然不能很好地支持像"纯函数"这样的概念.在实践中,绝大多数在委托类型之间进行转换的尝试都非常安全:从a转换Func<int, bool>
为a Predicate<int>
等等.
所以,有两件事,一件是向后看,另一件是向前看.倒退:如果我们不得不重新做一遍,我认为代表可能会在CLI中进行结构化输入.在设计一个全新的框架时,你并不总是知道哪些特性会有用,而迄今为止,非结构化的委托类型并不像预期的那样有用.前瞻:我希望在未来版本的CLR中看到更多功能,以实现更多的结构类型.例如,C#4中的"无pia"特征是关于使两种类型在语义上和结构上相同,但在不同的集合中定义,在逻辑上在结构上统一.
该错误的基本形式是:
delegate void d1();
delegate void d2();
d1 a;
d2 b;
b = a;
Error Cannot implicitly convert type 'ConsoleDemo1.d1' to 'ConsoleDemo1.d2'
Run Code Online (Sandbox Code Playgroud)
因此,您可以使用正确的委托类型来“解决”您的第一个示例:
//Action doIt;
ThreadStart doIt;
doIt = () => MyMethod("test");
Thread t = new Thread(doIt);
Run Code Online (Sandbox Code Playgroud)
我相信这应该有效?
Action doIt;
doIt = () => MyMethod("test");
Thread t;
t = new Thread(doIt.Invoke);
t.Start();
Run Code Online (Sandbox Code Playgroud)