C# 为什么任务没有';t返回空值
我正在与新员工合作,今天我们讨论了这个案例: 此代码不编译:C# 为什么任务没有';t返回空值,c#,task-parallel-library,C#,Task Parallel Library,我正在与新员工合作,今天我们讨论了这个案例: 此代码不编译: internal Task<Guid?> SavePages(string[] pages) { return Task.Run(() => { if (pages == null || pages.Length == 0) return null; .... 内部任务保存页(字符串[]
internal Task<Guid?> SavePages(string[] pages)
{
return Task.Run(() =>
{
if (pages == null || pages.Length == 0)
return null;
....
内部任务保存页(字符串[]页)
{
返回任务。运行(()=>
{
if(pages==null | | pages.Length==0)
返回null;
....
除非我显式返回空的可空Guid:
internal Task<Guid?> SavePages(string[] pages)
{
return Task.Run(() =>
{
if (pages == null || pages.Length == 0)
return (Guid?)null;
// Check documents path access
内部任务保存页(字符串[]页)
{
返回任务。运行(()=>
{
if(pages==null | | pages.Length==0)
返回(Guid?)null;
//检查文档路径访问
为什么会有这种行为,我做错了什么?我的意思是,我让代码使用第二个选项,但不知道我是否滥用了库,我的意思是,null总是null,不是吗
编译错误:
无法将lambda表达式转换为委托类型
“System.Func”因为返回
块中的类型不能隐式转换为委托
返回类型
这与编译器确定lambda类型的方式有关。当您返回纯
null
时,编译器只能暗示您正在返回一个对象。因此,无参数lambda与任务
兼容。但是,函数的签名表示您正在返回>任务
,因此编译器从代码中暗示的返回类型不兼容。当您将null
强制转换为Guid?
时,您向编译器提供了使lambda成为任务
的线索。这是C编译器中类型推断的限制。此问题与invol无关对三元运算符进行排序:
int? num = a != null ? a.Value : null; // Will not compile
int? num = a != null ? a.Value : (int?)null; // Compiles
int? num = a != null ? (int?)a.Value : null; // Compiles
针对特定情况的另一种解决方法是显式指定泛型类型:
return Task.Run<Guid?>(() =>
{
if (pages == null || pages.Length == 0)
return null;
返回任务。运行(()=>
{
if(pages==null | | pages.Length==0)
返回null;
FFR,包括确切的编译器错误将非常有用,因为在这种情况下,它可能会提到无法推断类型。问题是null始终为null,因此编译器无法知道您使用null表达式表示的是哪种类型侧注:与(Guid?.null
是新的Guid?()
和默认值(Guid?
)。编译器应该自己推断出这一点(尽管原因很清楚)@zmbq如何确定null
的类型?它是所有引用类型的有效值,因此编译器无法确定该表达式的类型(对象除外)@RuneFS假定它是一个可为空的类型,那么assign必须起作用,不是吗?可以从保存页的类型推断出该类型。@zmbq在C#中,类型推断不是这样工作的。通常,每个表达式的类型都是独立推断的(但lambda是一个例外).1道格拉斯的解释。一个问题:是否使用非通用版本的Task.Run(如您所建议的那样)以任何可能的方式降低性能?除非我遗漏了什么,否则他只是在说不要让编译器推断类型-无论哪种方式,都会得到相同的生成ILAFAICT@RandolfRincón-Fadul:我的代码仍然使用的是的泛型版本;事实上,它是显式使用的,而不是推断类型(就像您的代码那样)就像James Manning所说的,我不相信生成的IL会有什么不同,因为在编译时执行类型推断。显式指定泛型类型可能会使编译(不是运行时)稍微快一点,但这几乎是绝对不需要考虑的。