为什么我不能对 ThreadStart 使用/强制执行 Action?

Why can#39;t I use/cast an Action for/to a ThreadStart?(为什么我不能对 ThreadStart 使用/强制执行 Action?)
本文介绍了为什么我不能对 ThreadStart 使用/强制执行 Action?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

两者都是委托并且具有相同的签名,但我不能将 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?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)