- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我发现自己一直想传递一个有返回值且没有输入的 Func
来代替 Action
,例如
Func<int> DoSomething = ...;
Task.Run(DoSomething);
在哪里,我真的不关心 DoSomething
的返回值。
但是,这些类型并不统一,我最终结束了调用
Task.Run(() => { DoSomething(); });
有没有办法在不包装的情况下使这些类型统一?另外,它们不统一是否有好的设计原因?
最佳答案
您希望以下陈述为真:
If I have a
Func<T>
, I should be able to use it where anAction
is required.
这需要 Func<T>
(A) 可分配给 Action
或 (B) 隐式转换为 Action
.
如果我们假设 (A) 那将需要 T
,可以是任何类型,可分配给 void
.
Eric Lippert 在 his blog 中回答了这个问题:
Shouldn’t “void” be considered a supertype of all possible types for the purposes of covariant return type conversions from method groups to delegate types?
他的回答是“否”,因为这最终与 CLI 规范不兼容。 CLI 规范要求返回值进入堆栈,因此 void
函数最终不会生成“pop”指令,而那些返回某些东西的函数会生成“pop”指令。如果有某种方式可以包含一个“ Action ”void
函数或返回在编译时未知的东西的函数,编译器不知道是否生成“pop”指令。
他接着说:
Had the CLI specification said “the returned value of any function is passed back in a ‘virtual register’” rather than having it pushed onto the stack, then we could have made void-returning delegates compatible with functions that returned anything. You can always just ignore the value in the register. But that’s not what the CLI specified, so that’s not what we can do.
换句话说,如果有这个存储函数返回值的“虚拟寄存器”(在 CLI 规范中可能不存在),C# 及其编译器的编写者可以完成您想要的,但是他们不能,因为他们不能偏离 CLI 规范。
如果我们假设(B),就会出现重大变化,正如 Eric Lippert 在 this blog 中解释的那样.如果有从 Func<T>
的隐式转换,则将他博客中的示例改编为此示例至 Action
,一些程序不再编译(中断更改)。该程序目前可以编译,但尝试取消对隐式转换运算符的注释,类似于您所要求的,它不会编译。
public class FutureAction
{
public FutureAction(FutureAction action)
{
}
//public static implicit operator FutureAction(Func<int> f)
//{
// return new FutureAction(null);
//}
public static void OverloadedMethod(Func<FutureAction, FutureAction> a)
{
}
public static void OverloadedMethod(Func<Func<int>, FutureAction> a)
{
}
public static void UserCode()
{
OverloadedMethod(a => new FutureAction(a));
}
}
(这显然不是他们要做的,因为这只适用于 Func<int>
而不是 Func<T>
,但它说明了问题。)
总结
我认为您面临的问题是 CLI 规范的产物,当时可能没有预见到,我猜他们不想引入重大更改以允许隐式转换为工作。
关于c# - 为什么 Func<...> 和 Action 不统一?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33150506/
我在等待异步功能完成时苦苦挣扎。特别是,我发现这两种方法在测试继续之前等待异步函数完成,但不知道其中的区别(如果有区别的话):。我的目标是在实际测试开始之前等待bepreEach()块中的两个异步函数
我在等待异步功能完成时苦苦挣扎。特别是,我发现这两种方法在测试继续之前等待异步函数完成,但不知道其中的区别(如果有区别的话):。我的目标是在实际测试开始之前,在beforeEach()块中等待两个Ja
为什么是Func<>从 Expression> 创建通过 .Compile() 比仅使用 Func<> 慢得多直接声明? 我刚从使用 Func 更改为直接声明为从 Expression> 创建的一个在
我正在创建一个 Validator类(class)。我正在尝试实现 Linq SelectMany我的验证器的扩展方法能够使用 Linq 查询组合表达式并验证最终结果,即使基础值发生变化也是如此。 下
function sum(a) { let currentSum = a; function f(b) { currentSum += b; return f; }
我只知道i = i++;是未定义的行为,但是如果一个表达式中调用了两个或多个函数,并且所有功能是一样的。是未定义吗?例如: int func(int a) { std::cout << a <
我如何定义一个对象,以便作用于它的任何函数都作用于它的一个字段?这可能吗? class Mydata(object): def __init__(self, val): sel
这个问题一直很有趣,尽管它不一定很整洁。我有以下代码: import random def d(m): return random.randint(1, m) print(3*d(6)) 这将
能否请您解释一下使用 func.apply(null, arr) 的区别?和 func.apply(this, arr)在下面的代码示例中? var Foo = function() { fu
我想收集/运行任务,然后对它们执行 Task.WhenAll。 var tasks = new List(); foreach (var thing in things) { tasks.Add(
我有以下代码: static Func s_objToString = (x) => x.ToString(); static Func s_stringToString = s_objToStrin
相关主题: Create Expression> dynamically 我在互联网上搜索但所有样本都解释了 Expression来自 T ? 谢谢 编辑 1) T输入我的代码在运行时确定,例如我想用
我正在尝试使用 LinqKit 动态生成 linqtosql 查询.在将表达式发送到 LinqKit 之前,我想检查要为预测添加的字段。所以我想出了一些想法,比如 Expression> GetPr
我遇到了一些麻烦,我写了一个 Func,IDE 不喜欢我在 Func 体内调用 Func ,我不太明白为什么,因为如果我将这个确切的代码放在方法体中,并使用相同的返回类型和参数,那么它就可以工作。 代
我现在正在学习使用 Class 语法来创建 React 组件,请注意我现在必须声明这样的方法: class Foo extends React.Component { ... bar
下面两种说法有区别吗?他们都工作。 if ( ((Func)(()=>true))() ) { .... }; if ( new Func(()=>true)()) { .... }; 最佳答案 不,
这个问题在这里已经有了答案: Difference between func() and (*this).func() in C++ (4 个答案) 关闭 6 年前。 如果我有一个带有虚函数而没有自
主要问题是“是否可以将任何类型的 func 作为参数传递以及如何传递?”。我正在学习 Go 并且想像这样制作我自己的异步包装函数: func AsyncFunc(fn func(), args ...
有没有简单的转换方法 Expression> 到 Expression> T从哪里继承自TBase? 最佳答案 只要 T 派生自 TBase,您就可以使用原始表达式的主体和参数直接创建所需类型的表达式
我有以下方法,其中 T 在 Func 中使用: public void DoSomething(string someString, Func someMethod) { if(some
我是一名优秀的程序员,十分优秀!