为啥 Roslyn 在尝试重写此 lambda 时会崩溃? (Visual Studio 2015 更新 1)
Posted
技术标签:
【中文标题】为啥 Roslyn 在尝试重写此 lambda 时会崩溃? (Visual Studio 2015 更新 1)【英文标题】:Why does Roslyn crash when trying to rewrite this lambda? (Visual Studio 2015 update 1)为什么 Roslyn 在尝试重写此 lambda 时会崩溃? (Visual Studio 2015 更新 1) 【发布时间】:2016-03-09 05:03:00 【问题描述】:我刚刚升级到 VS2015.1,在尝试编译我的一个项目时遇到了编译器崩溃。如果您将以下 repo 代码放在控制台应用程序中(并添加对 moq.dll 的引用),第 12 行中的代码会使我的编译器崩溃。这似乎发生在 Roslyn lamdba 重写调用期间。
using System.Collections.Generic;
using System.Linq;
using Moq;
namespace RoslynError
class Program
static void Main(string[] args)
var mockRepo = new MockRepository(MockBehavior.Strict);
var obj = mockRepo.OneOf<DTO>(x => x.Value == (OptionEnum?)null);
class DTO
public DTO(OptionEnum? enumVal)
Value = enumVal;
public OptionEnum? Value;
enum OptionEnum
NotSpecified
有人知道为什么会发生崩溃吗?
【问题讨论】:
对起订量的引用几乎不相关。我认为重要的是 lambda 箭头将被转换为表达式树(Expression<Func<DTO, bool>>
类型),而不是简单的委托实例(Func<DTO, bool>
类型)。
【参考方案1】:
下面更简单的例子也重现了这个问题,这与重写表达式树中的类型转换节点有关:
using System;
using System.Linq.Expressions;
namespace Bug461
class Program
enum Test
static void Main()
Expression<Func<Test?, bool>> x = t => t == (Test?)null;
编辑:我稍微编辑了代码以避免出现警告。
编辑 2:该错误是由https://github.com/dotnet/roslyn/commit/5c602fc6 引起的,其中降级的枚举操作数(即 null 文字)没有关联类型。
编辑 3:我提出了一个带有建议修复的拉取请求:https://github.com/dotnet/roslyn/pull/7227
【讨论】:
在tryroslyn.azurewebsites.net 编译。将不可为空的t
与null
进行比较是一个有效的警告。在问题的代码中,==
运算符的两边都已经可以为空(没有换行)。
是的,但是当我在 Visual Studio 中本地编译它时它仍然崩溃,尽管只安装了 VS 2015 更新 1。
@SuneFoldager:因为您发出了无效代码:D 请参阅 PR 中的测试失败。 PS:你还应该在你的 PR 中添加测试。
@leppie:是的,我更新了 PR。诀窍是在我们有显式可空类型转换的情况下不应用 github.com/dotnet/roslyn/commit/5c602fc6 中的缩减。不幸的是,我们似乎无法完全区分这些情况:(
我的 PR 已合并。以上是关于为啥 Roslyn 在尝试重写此 lambda 时会崩溃? (Visual Studio 2015 更新 1)的主要内容,如果未能解决你的问题,请参考以下文章
使用 Roslyn 生成 getter 和 setter lambda
在 python 3 中使用 map 和 lambdas,为啥这段代码不会更新 sql 表