问题描述
两者都是委托并且具有相同的签名,但我不能将 Action 用作 ThreadStart.
Both are delegates and have the same signature, but I can not use Action as ThreadStart.
为什么?
Action doIt;
doIt = () => MyMethod("test");
Thread t;
t = new Thread(doIt);
t.Start();
但这似乎有效:
Thread t;
t = new Thread(() => MyMethod("test"));
t.Start();
推荐答案
正如其他人所指出的,问题在于委托类型不是结构的".也就是说,它们不具有基于它们的结构"的等价性.
As others have noted, the problem is that delegate types are not "structural". That is, they do not have equivalence based on their "structure".
现在,对于某些类型来说,这可以说是一件好事.如果你有
Now, this is arguably a good thing for some types. If you have
struct MyRectangle { int x; int y; int width; int height; ... }
和
struct YourRectangle { int x1; int y1; int x2; int y2; ... }
显然,允许将 MyRectangle 的实例分配给 YourRectangle 的变量是错误的,因为它们都由四个整数组成.int 的语义不同,因此类型不等价.
obviously it would be a mistake to allow instances of MyRectangle to be assigned to variables of YourRectangle, just because they both consisted of four ints. The semantics of the ints are different and therefore the types are not equivalent.
理论上,代表也是如此.你可以有
The same is, in theory, true of delegates. You could have
delegate int Pure(string x);
delegate int Func(string x);
纯"函数是没有副作用且在相同输入下输出相同的函数.由于每个 Pure 在逻辑上都是 Func,但每个 Func 不一定是 Pure,它们之间不应该存在结构类型.
where a "pure" function is one with no side effects and the same output given the same input. Since every Pure is logically a Func, but every Func is not necessarily a Pure, there shouldn't be structural typing between them.
在实践中,类型系统当然不能很好地支持像纯函数"这样的概念.在实践中,绝大多数委托类型之间的转换尝试都是非常安全的:从 Func
转换为 Predicate
In practice of course the type system does not support notions like "pure function" very well. And in practice, the vast majority of attempts to convert between delegate types are perfectly safe: converting from a Func<int, bool>
to a Predicate<int>
and so on.
所以,有两件事,一件向后看,一件向前看.向后:如果我们必须重新做一遍,我认为委托可能会在 CLI 中进行结构类型化.当您设计一个全新的框架时,您并不总是知道哪些功能会很有用,而且到目前为止,非结构委托类型已被证明不如预期的那么有用.前锋:我希望在 CLR 的未来版本中看到更多功能,这些功能支持更多的结构化类型.例如,C# 4 中的no pia"特性是关于使两种在语义和结构上相同但在不同程序集中定义的类型在结构上在逻辑上统一.
So, two things, one looking backwards and one looking forwards. Backwards: if we had to do it all over again, I think delegates would probably be structurally typed in the CLI. You don't always know what features are going to be useful when you design a brand new framework, and non-structural delegate types have thus far turned out to be not as useful as perhaps anticipated. Forwards: I expect to see more features in future versions of the CLR that enable more structural typing. The "no pia" feature in C# 4, for example, is about making two types that are semantically and structurally the same, but defined in different assemblies, logically unify structurally.
这篇关于为什么我不能对 ThreadStart 使用/强制执行 Action?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!