ใช้ System.Dynamic ใน Roslyn


96

ฉันแก้ไขตัวอย่างที่มาพร้อมกับ Roslyn เวอร์ชันใหม่ที่เปิดตัวเมื่อวานนี้เพื่อใช้ไดนามิกและ ExpandoObject แต่ฉันได้รับข้อผิดพลาดของคอมไพเลอร์ซึ่งฉันไม่แน่ใจว่าจะแก้ไขอย่างไร ข้อผิดพลาดคือ:

(7,21): ข้อผิดพลาด CS0656: ไม่มีสมาชิกที่ต้องการของคอมไพเลอร์ 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create'

คุณยังไม่สามารถใช้ dynamics ในคอมไพเลอร์ใหม่ได้หรือไม่? ฉันจะแก้ไขปัญหานี้ได้อย่างไร? นี่คือตัวอย่างที่ฉันอัปเดต:

[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> ข้อผิดพลาดของคอมไพเลอร์หายไปแล้ว
Don Rolling

3
FWIW การเพิ่ม Microsoft.CSharp.dll หมายถึง var scriptOptions = ScriptOptions.Default WithReferences ("Microsoft.CSharp") เช่นปล่อย dll ทำให้ฉันนิ่งงันสักสองสามนาที :)
Jon H

@JonH ดังนั้นเราควรเพิ่มบรรทัดนั้นใน AssemblyInfo.cs หรือที่ไหนสักแห่งแทนที่จะอ้างถึง dll?
เอช.

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 ทั้งหมดนี้เป็นสตริง
Simon Mourier

7

ASP.NET MVC เฉพาะ:

คุณจะได้รับข้อผิดพลาดนี้ใน MVC 6 ควบคุมถ้าคุณลืมที่จะใส่[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 เพื่อแก้ไขข้อผิดพลาดนี้ได้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.