Использование System.Dynamic в Roslyn


96

Я изменил пример, который поставляется с новой версией Roslyn, которая была выпущена вчера, чтобы использовать динамический и ExpandoObject, но я получаю ошибку компилятора, которую я не знаю, как исправить. Ошибка:

(7,21): ошибка CS0656: отсутствует обязательный член компилятора Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create

А динамику в новом компиляторе пока нельзя использовать? Как я могу это исправить? Вот обновленный мной пример:

[TestMethod]
public void EndToEndCompileAndRun()
{
    var text = @"using System.Dynamic;
    public class Calculator
    {
        public static object Evaluate()
        {
            dynamic x = new ExpandoObject();
            x.Result = 42;
            return x.Result;
        } 
    }";

    var tree = SyntaxFactory.ParseSyntaxTree(text);
    var compilation = CSharpCompilation.Create(
        "calc.dll",
        options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary),
        syntaxTrees: new[] {tree},
        references: new[] {new MetadataFileReference(typeof (object).Assembly.Location), new MetadataFileReference(typeof (ExpandoObject).Assembly.Location)});

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

    Type calculator = compiledAssembly.GetType("Calculator");
    MethodInfo evaluate = calculator.GetMethod("Evaluate");
    string answer = evaluate.Invoke(null, null).ToString();

    Assert.AreEqual("42", answer);
}

Ответы:


219

Я думаю, что стоит ссылаться на Microsoft.CSharp.dllсборку


3
Да, это то, что требовалось с момента dynamicего появления.
khellang

19
И если бы Microsoft выдала сообщение об ошибке, в котором говорилось, что это значительно упростит задачу.
kjbartel

1
Я не знаю, устранило ли это проблему или нет, но я добавил <add namespace = "Microsoft.CSharp" /> в свой узел Views / Web.config <namespaces>. Ошибка компилятора исчезла.
Дон Роллинг,

3
FWIW добавление Microsoft.CSharp.dll означает var scriptOptions = ScriptOptions.Default.WithReferences ("Microsoft.CSharp"), т.е. удаление dll. Остановил меня на несколько минут :)
Jon H

@JonH, поэтому мы должны добавить эту строку в AssemblyInfo.cs или где-то еще вместо ссылки на dll?
NH.

9

Чтобы код работал в .Net Core 2.1, мне пришлось добавить эти ссылки в компиляцию:

var compilation = CSharpCompilation.Create(
    "calc.dll",
    options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary),
    syntaxTrees: new[] {tree},
    references: new[] {
        MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
        MetadataReference.CreateFromFile(typeof(ExpandoObject).Assembly.Location),
        MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("Microsoft.CSharp")).Location),
        MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("netstandard")).Location),
        MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("mscorlib")).Location),
        MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Runtime")).Location),            
    }
);

Вы можете обойтись без System.Linq.Expressions, System.Private.CoreLib, System.Runtime и Microsoft.CSharp, все в виде строк
Саймон Мурье

7

Специфика ASP.NET MVC:

Вы можете получить эту ошибку в 6 контроллера MVC , если вы забыли поставить [FromBody]в POSTметоде.

    [HttpPost("[action]")]
    public void RunReport([FromBody]dynamic report)
    {
        ...
    }

В проект .NETCore по умолчанию уже включена Microsoft.CSharpссылка, но вы получите примерно то же сообщение.

С [FromBody]добавлением теперь вы можете отправлять JSON, а затем просто динамически получать доступ к свойствам :-)


Подумал, что это не относится к исходному вопросу, опубликованному в 2014 году (хотя хотел признать, что это было полезно.) Не был уверен, что такое этикет SO в такой ситуации.
tj

Справедливый вопрос :) Я просто добавил его сюда, потому что он казался таким непонятным, и это хорошо соответствовало той ошибке
Simon_Weaver

4

Вы также можете проверить свойства всех ссылок на ваш проект. Убедитесь, что в любой ссылке используется .NET новее 2.0. У меня есть проект, который ссылался на другой проект в том же решении, и мне пришлось перестраивать зависимость с использованием новой целевой платформы .NET.

См. Этот пост .

Кроме того, не забудьте добавить Microsoft.CSharpссылку на ваш основной проект, как сказал @Alberto.


1

Если ваш проект нацелен на .Net Core или .Net Standard, то вместо добавления ссылки вы можете установить пакет Microsoft.CSharp NuGet для устранения этой ошибки.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.