Menggunakan System.Dynamic di Roslyn

96

Saya memodifikasi contoh yang datang dengan versi baru Roslyn yang dirilis kemarin untuk menggunakan dinamis dan ExpandoObject tetapi saya mendapatkan kesalahan kompiler yang saya tidak yakin bagaimana memperbaikinya. Kesalahannya adalah:

(7,21): kesalahan CS0656: Anggota yang tidak ada compiler 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create'

Bisakah Anda belum menggunakan dinamika di kompiler baru? Bagaimana cara memperbaikinya? Berikut contoh yang saya perbarui:

[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);
}
Rush Frisby
sumber

Jawaban:

219

Saya pikir Anda harus merujuk Microsoft.CSharp.dllmajelis

Alberto
sumber
3
Ya, ini adalah sesuatu yang sudah dibutuhkan sejak dynamicdiperkenalkan.
khellang
19
Dan jika Microsoft memberikan pesan kesalahan yang memberi tahu Anda bahwa ini akan membuat segalanya menjadi lebih mudah.
kjbartel
1
Saya tidak tahu apakah ini memperbaiki masalah atau tidak, tetapi saya menambahkan <add namespace = "Microsoft.CSharp" /> ke simpul Views / Web.config <namespaces> saya. Kesalahan kompilator sekarang hilang.
Don Rolling
3
FWIW menambahkan Microsoft.CSharp.dll berarti var scriptOptions = ScriptOptions.Default.DenganReferences ("Microsoft.CSharp") yaitu jatuhkan dll. Membuat saya bingung selama beberapa menit :)
Jon H
@ JonH jadi kita harus menambahkan baris itu ke AssemblyInfo.cs atau di suatu tempat daripada mereferensikan dll?
NH.
9

Untuk membuat kode berfungsi di .Net Core 2.1 saya harus menambahkan referensi ini dalam kompilasi:

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),            
    }
);
Renzo Ciot
sumber
Anda bisa lolos dengan System.Linq.Expressions, System.Private.CoreLib, System.Runtime dan Microsoft.CSharp, semuanya sebagai string
Simon Mourier
7

ASP.NET MVC spesifik:

Anda bisa mendapatkan kesalahan ini dalam MVC 6 kontroler jika Anda lupa untuk menempatkan [FromBody]dalam POSTmetode.

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

Proyek default .NETCore sudah menyertakan Microsoft.CSharpreferensi tetapi Anda mendapatkan pesan yang hampir sama.

Dengan [FromBody]menambahkan Anda sekarang dapat memposting JSON dan kemudian mengakses properti secara dinamis :-)

Simon_Weaver
sumber
Kupikir itu tidak berlaku untuk pertanyaan asli yang diposting dari 2014 (meskipun ingin mengakui bahwa itu membantu.) Tidak yakin apa yang didiktekan oleh etiket SO dalam situasi seperti itu.
tj
Poin yang adil :) Saya baru saja menambahkannya di sini karena tampaknya sangat tidak jelas dan ini cocok untuk kesalahan itu
Simon_Weaver
4

Anda mungkin juga ingin memeriksa properti dari semua referensi proyek Anda. Pastikan referensi apa pun menggunakan .NET yang lebih baru dari 2.0. Saya memiliki proyek yang mereferensikan proyek lain dalam solusi yang sama dan harus membangun kembali ketergantungan menggunakan target kerangka .NET yang lebih baru.

Lihat posting ini .

Juga, jangan lupa untuk menambahkan Microsoft.CSharpreferensi ke proyek utama Anda seperti yang dikatakan @Alberto.

A. Clymer
sumber
1

Jika proyek Anda menargetkan .Net Core atau .Net Standard, alih-alih menambahkan referensi, Anda dapat menginstal paket Microsoft.CSharp NuGet untuk mengatasi kesalahan ini.

Kolappan N
sumber