【问题标题】:Could Roslyn compile await keyword?Roslyn 可以编译 await 关键字吗?
【发布时间】:2013-03-10 01:49:37
【问题描述】:

在使用最新版本的 时,我发现它在编译和脚本执行时不支持dynamic 关键字,即你会得到一个编译错误error CS8000: This language feature ('dynamic') is not yet implemented in Roslyn. 这是一个短代码sn-p:

var engine = new ScriptEngine();
var script = @"dynamic someVariable = 0;";
// you an error CS8000: This language feature ('dynamic') is not yet implemented in Roslyn
engine.CreateSession().Execute(script);

在使用 await 关键字时……

相比之下,在编译或脚本中使用 await 关键字时,我通常会遇到一些随机编译错误,如下所示:

  • error CS1001: Identifier expected
  • error CS1003: Syntax error, ',' expected
  • error CS0246: The type or namespace name 'await' could not be found (are you missing a using directive or an assembly reference?)

脚本示例

var engine = new ScriptEngine();

new[]
{
    "System", "System.Threading", "System.Threading.Tasks",
} .ToList().ForEach(@namespace => engine.ImportNamespace(@namespace));

var script = @"await Task.Run(() => System.Console.WriteLine(""Universal [async] answer is '42'""));";

engine.CreateSession().Execute(script);

编译示例

// compilation sample
const string codeSnippet = @"namespace DemoNamespace
    {
        using System;
        using System.Threading;
        using System.Threading.Tasks;

        public class Printer
        {
            public async void Answer() 
            {
                var answer = 42;
                var task = Task.Run(() => System.Console.WriteLine(string.Format(""Universal [async] answer is '{0}'"", answer)));
                await task; // not working
                task.Wait(); // working as expected
            }
        }
     }";

var syntaxTree = SyntaxTree.ParseText(codeSnippet,
     options: new ParseOptions(languageVersion: LanguageVersion.CSharp5));

var references = new []
{
    MetadataReference.CreateAssemblyReference(typeof(Console).Assembly.FullName),
    MetadataReference.CreateAssemblyReference(typeof(System.Threading.Tasks.Task).Assembly.FullName),
};

var compilation = Compilation.Create(
                        outputName: "Demo", 
                        options: new CompilationOptions(OutputKind.DynamicallyLinkedLibrary),
                        syntaxTrees: new[] { syntaxTree },
                        references: references);

if(compilation.GetDiagnostics().Any())
{
    compilation.GetDiagnostics().Select(diagnostic => diagnostic).Dump();
    throw new Exception("Compilation failed");
}

Assembly compiledAssembly;
using (var stream = new MemoryStream())
{
    EmitResult compileResult = compilation.Emit(stream);
    compiledAssembly = Assembly.Load(stream.GetBuffer());
}

dynamic instance = Activator.CreateInstance(compiledAssembly.GetTypes().First());
instance.Answer();

:是我遗漏了什么还是尚未实现?

我尝试了使用LanguageVersion.CSharp5 和不使用的不同配置。谷歌和 Stackoverflow 搜索都充斥着 关键字的营销炒作,几乎没用。 Microsoft "Roslyn" CTP forum 也没有答案。

ps:据我所知,async 引入了关键字以提高人类和编译器的可读性,而 await 做到了所有魔法

【问题讨论】:

    标签: roslyn-ctp roslyn async c# async-await c#-5.0 roslyn


    【解决方案1】:

    await 支持未在当前 Roslyn CTP 中实现(尽管它现在已在内部构建中实现)。

    错误报告不同的原因是我们首先构建了 Roslyn 解析器,以便它可以处理整个 C# 4 语言,然后一次为特性填充语义。由于await 是C# 5 的特性,它甚至不被解析器识别,也没有地方识别它的使用并提供一个很好的错误。

    【讨论】:

    • 关于何时发布此内部版本(或新 CTP)的任何计划?
    • 真期待下一次降码!我希望能够生成利用 System.Net.Http.HttpClient 异步支持的类。
    【解决方案2】:

    实际上,罗斯林论坛确实有答案。如果您查看帖子 Known Limitations and Unimplemented Language Features,您会注意到它包含 C# 中尚未实现的功能中的“异步”。

    该列表是关于 6 月 CTP,但由于 the list of changes between the June CTP and the December CTP 没有列出异步,这意味着它还没有实现。

    我认为错误消息不同的原因是 Roslyn 确实理解 dynamic(但还没有实现它)。另一方面,它不理解async-await,所以它会给你一般的编译错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      • 2011-12-11
      • 2016-12-30
      • 2017-04-25
      • 1970-01-01
      相关资源
      最近更新 更多