Roslyn还出现这么低级的错误,不应该呀!

前几天对Dora.Interception作了简单的重构,想提供C#脚本来定义Interception Policy,毫无疑问微软提供的编译平台Roslyn使C#脚本化提供了支持。但是没有想到随便尝试了一个简单的功能就出现了问题,我个人觉得这应该是Roslyn的Bug。但是Roslyn经历了这么多次版本的迭代还出现如此低级的错误,实在有点说不过去。

闲话少说,我们现在通过几行简单的代码来重现这个Bug。我们创建了一个.NET Core 2.1的控制台应用,并添加针对NuGet包”Microsoft.CodeAnalysis.CSharp.Scripting“(版本2.8.2)的依赖。如下所示的是.csproj的完整定义。

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp2.1</TargetFramework>
        <AssemblyName>App</AssemblyName>
        <RootNamespace>App</RootNamespace>
    </PropertyGroup>
    <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
        <LangVersion>7.3</LangVersion>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="2.8.2" />
    </ItemGroup>
</Project>

接下来我们编写了一段简单的程序。如下面的代码片段所示,我们只是采用脚本的形式创建了一个Foo对象并利用它创建出Bar对象,然后调用后者的Print方法而已。

namespace Scripting
{
    public class Foo { }
    public class Bar
    {
        public Foo Foo { get; }
        public Bar(Foo foo) => Foo = foo;
        public void Print() => Console.WriteLine(Foo);
    }

    class Program
    {
        static async Task Main(string[] args)
        {
            var options = ScriptOptions.Default
                .AddReferences(typeof(Program).Assembly)
                .AddImports("Scripting");

            //Success
            await CSharpScript
               .Create("var bar = new Bar(new Foo());", options)
               .ContinueWith("bar.Print()")
               .RunAsync();
        }
    }
}

这段代码是没有问题的,运行之后Print方法输出的结果可以正常出现在入下所示的控制台上。

接下来我们将“var bar = new Bar(new Foo());”这行代码按照如下的方式拆分成两行执行。

class Program
{
    static async Task Main(string[] args)
    {
        //Fail
        await CSharpScript
            .Create("var foo = new Foo();", options)
            .ContinueWith("var bar = new Bar(foo);")
            .ContinueWith("bar.Print()")
            .RunAsync();
    }
}

在此运行该程序后出现如下所示的“Microsoft.CodeAnalysis.Scripting.CompilationErrorException”异常,并提示“cannot convert from 'Scripting.Foo [App, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]' to 'Scripting.Foo [c:\users\jinnan\Source\Repos\App\App\bin\Debug\netcoreapp2.1\App.dll]”。

如下所示的是完整的错误信息:

Unhandled Exception: Microsoft.CodeAnalysis.Scripting.CompilationErrorException: (1,19): error CS1503: Argument 1: cannot convert from 'Scripting.Foo [App, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]' to 'Scripting.Foo [c:\users\jinnan\Source\Repos\App\App\bin\Debug\netcoreapp2.1\App.dll]'
   at Microsoft.CodeAnalysis.Scripting.ScriptBuilder.ThrowIfAnyCompilationErrors(DiagnosticBag diagnostics, DiagnosticFormatter formatter) in /_/src/Scripting/Core/ScriptBuilder.cs:line 104
   at Microsoft.CodeAnalysis.Scripting.ScriptBuilder.CreateExecutor[T](ScriptCompiler compiler, Compilation compilation, Boolean emitDebugInformation, CancellationToken cancellationToken) in /_/src/Scripting/Core/ScriptBuilder.cs:line 89
   at Microsoft.CodeAnalysis.Scripting.Script`1.GetExecutor(CancellationToken cancellationToken) in /_/src/Scripting/Core/Script.cs:line 359
   at Microsoft.CodeAnalysis.Scripting.Script`1.CommonGetExecutor(CancellationToken cancellationToken) in /_/src/Scripting/Core/Script.cs:line 343
   at Microsoft.CodeAnalysis.Scripting.Script`1.TryGetPrecedingExecutors(Script lastExecutedScriptInChainOpt, CancellationToken cancellationToken) in /_/src/Scripting/Core/Script.cs:line 407
   at Microsoft.CodeAnalysis.Scripting.Script`1.GetPrecedingExecutors(CancellationToken cancellationToken) in /_/src/Scripting/Core/Script.cs:line 370
   at Microsoft.CodeAnalysis.Scripting.Script`1.RunAsync(Object globals, Func`2 catchException, CancellationToken cancellationToken) in /_/src/Scripting/Core/Script.cs:line 459
   at Scripting.Program.Main(String[] args) in c:\users\jinnan\Source\Repos\App\App\Program.cs:line 31
   at Scripting.Program.<Main>(String[] args)

这是我提交的issue链接:https://github.com/dotnet/roslyn/issues/28803#issuecomment-407894956

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏刘望舒

LeakCanary看这一篇文章就够了

LeakCanary是Square公司基于MAT开源的一个内存泄漏检测工具,在发生内存泄漏的时候LeakCanary会自动显示泄漏信息。

9845
来自专栏c#开发者

Biztalk Server zip unzip pipeline component Development

Biztalk Server zip unzip pipeline component Development 最近有个B2B的项目涉及和其他合作伙伴(part...

3514
来自专栏逸鹏说道

EntityFramework教程整理

ASP.NET MVC 系列文章 以下文章属于ASP.NET MVC 1.0 正式版 ASP.NET MVC雕虫小技 1-2 ASP.NET MVC 重点教程一...

2836
来自专栏大内老A

EnterLib PIAB又一个BUG?

在《这是EnterLib PIAB的BUG吗?》一文中我们讨论了PIAB关于抽象基类的BUG,今天又发现了一个新的问题。问题的起因源于《IoC+AOP的简单实现...

1769
来自专栏芋道源码1024

【RPC 专栏】简单了解RPC实现原理

3216
来自专栏林德熙的博客

WPF 拼音输入法

实际上本文是在使用一个好用的软件 希沃白板 的时候发现在里面很难输入拼音来做课堂活动。

3932
来自专栏林德熙的博客

dotnet core 黑科技·String.IndexOf 性能

本文来告诉大家 dotnet core 里面使用的黑科技,如何提高String.IndexOf(char)的性能

1181
来自专栏恰同学骚年

ASP.Net请求处理机制初步探索之旅 - Part 5 ASP.Net MVC请求处理流程

开篇:上一篇我们了解了在WebForm模式下一个Page页面的生命周期,它经历了初始化Init、加载Load以及呈现Render三个重要阶段,其中构造了页面控件...

1293
来自专栏debugeeker的专栏

source insight coredump分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xuzhina/article/detai...

671
来自专栏张善友的专栏

ASP.NET AJAX 控件开发基础

在 JavaScript 当前广泛使用的版本中,它缺少 .NET 开发人员所熟悉的几个 OOP 的关键概念,而 ASP.NET AJAX 可以模拟其中的大多数,...

2096

扫码关注云+社区