Использование 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, а затем просто динамически получать доступ к свойствам :-)

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

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

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

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

А. Климер
источник
1

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

Колаппан Н
источник