การสร้าง VS2015 ล้มเหลวโดยไม่มีข้อผิดพลาดกับ Dynamic


136

ฉันกำลังเขียนการทดสอบหน่วยในโค้ดที่ส่งคืน JSON ประเภทที่ส่งคืนเป็นชนิดไม่ระบุชื่อดังนั้นฉันคิดว่าจะตรวจสอบค่าที่อยู่บนมันฉันแค่โยนวัตถุไปที่ a dynamicเพื่อยืนยัน

อย่างไรก็ตามเมื่อฉันทำอย่างนั้นงานสร้างของฉันล้มเหลว แต่ฉันไม่มีข้อความแสดงข้อผิดพลาด ฉันสามารถทำซ้ำสิ่งนี้ด้วยรหัสที่ง่ายมากในโครงการทดสอบหน่วยใหม่:

[TestMethod]
public void TestMethod1()
{
    var obj = new { someValue = true };

    dynamic asDynamic = obj;

    Assert.IsTrue(asDynamic.someValue);
}

ดูด้านล่างสำหรับสกรีนช็อตของบิลด์ที่ล้มเหลว

สร้างความล้มเหลว

งานสร้างสำเร็จเมื่อฉันพูดถึงการยืนยันว่า:

สร้างที่ประสบความสำเร็จโดยไม่ต้องยืนยัน

ในทางตรงกันข้ามฉันรันโค้ดต่อไปนี้ใน LinqPad 5 เบต้า (ซึ่งใช้คอมไพเลอร์ Roslyn) และไม่มีปัญหา:

var obj = new { someValue = true };
dynamic asDynamic = obj;
Console.WriteLine((asDynamic.someValue == true).ToString());

จริง

เกิดอะไรขึ้นที่นี่? เนื่องจากข้อผิดพลาดไม่แสดงฉันไม่สามารถบอกได้ว่าฉันใช้dynamicอย่างไม่ถูกต้องหรือไม่พบว่าเกินพิกัดที่ใช้สำหรับIsTrue()เพราะdynamicหรือถ้านี่เป็นข้อผิดพลาดในคอมไพเลอร์ (แม้ว่าฉันจะสงสัยอย่างนี้ ฉันไม่มีหลักฐานใด ๆ ว่ามีบางอย่างผิดปกติกับรหัสของฉัน)

เกี่ยวกับปัญหาการโอเวอร์โหลดฉันพยายามAssert.IsTrue((bool)asDynamic.someValue);แต่บิลด์ยังคงล้มเหลวยังไม่มีข้อความแสดงข้อผิดพลาด

ต่อความคิดเห็นของ @ RonBeyer ฉันได้ลองคัดเลือกนักแสดงมากขึ้นเช่นด้านล่างนี้เพื่อประโยชน์:

    dynamic asDynamic = (dynamic)obj;
    Assert.IsTrue(((dynamic)asDynamic).someValue);

    Assert.IsTrue((bool)asDynamic.somevalue);

เมื่อตรวจสอบอย่างใกล้ชิดฉันพบว่ามีข้อผิดพลาดปรากฏในหน้าต่างผลลัพธ์:

c: ... \ DynamicBuildFailTest \ UnitTest1.cs (16,33,16,42): ข้อผิดพลาด CS0656: สมาชิกคอมไพเลอร์ที่ขาดหายไปต้องการ 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create'

โอเค VS2013 ดีกว่าในการรายงานข้อผิดพลาดฉันจะค้นหาตามที่:

ป้อนคำอธิบายรูปภาพที่นี่

ตกลงเพิ่มการอ้างอิงถึง Microsoft.CSharp แก้ไขข้อผิดพลาดในการสร้างแต่ฉันจะเปิดคำถามนี้ไว้เพราะมันน่าจะเป็นปัญหากับ VS2015 ที่ (ในใจของฉัน) ควรได้รับการแก้ไข


คุณแน่ใจหรือว่ามันเป็นความล้มเหลวในการคอมไพล์แทนที่จะเป็นลิงค์ที่ล้มเหลว?
David W

คุณลองได้dynamic asDynamic = (dynamic)obj;ไหม Assert.IsTrue(((dynamic)obj).someValue);หรือเพียงแค่ในยืนยันแสดงความคิดเห็นออกมาแบบไดนามิกและการเขียน
Ron Beyer

@ RonBeyer ใช่ฉันได้ลองทั้งสองอย่างแล้วไม่ใช่โชคดี
DLeh

อีกหนึ่ง ... Assert.IsTrue((bool)asDynamic.someValue);?
Ron Beyer

1
ฉันพบปัญหาเดียวกันใน VS2015 ขณะที่พยายามใช้ไดนามิกในวิธีทดสอบ การสร้างล้มเหลวโดยไม่มีข้อผิดพลาด และหลังจากเพิ่มการอ้างอิง Microsoft.CSharp การสร้างสำเร็จแล้ว
Sarath Rachuri

คำตอบ:


226

มีข้อผิดพลาดของคอมไพเลอร์ Visual Studio 2015 ไม่รายงานข้อผิดพลาดอย่างถูกต้อง อย่างไรก็ตาม Visual Studio 2013 ทำ:

นี่คือคำตอบที่นี่: https://stackoverflow.com/a/13568247 :

ในระยะสั้น:

เพิ่มการอ้างอิงถึง Microsoft.CSharp เพื่อใช้dynamicเช่นนี้


9
เพิ่มการอ้างอิงถึงMicrosoft.CSharpdll แม้ว่าusing Microsoft.CSharp;จะไม่ได้เกิดข้อผิดพลาดในการรวบรวมเวลา
Barry Guvenkaya

45
ด้วย. NET Core ให้เพิ่มแพ็คเกจ NuGet Microsoft.CSharpแทน
Bart Verkoeijen

6
เช่นเดียวกับไลบรารีคลาส. Net Standard ที่ใช้ - เพิ่มแพ็คเกจ NuGet Microsoft.CSharp
ฮง

50

ในฐานะที่เป็นคนสองคนได้ตั้งข้อสังเกตในการแสดงความคิดเห็นสำหรับโปรเซสเซอร์ Core และ NetStandard สุทธิปัญหานี้บางครั้งจะได้รับการแก้ไขโดยการเพิ่มการอ้างอิง NuGet Microsoft.CSharpไป


3
วิธีนี้แก้ไขปัญหาของฉันหลังจากแปลงโครงการเป็น. NET มาตรฐานขอบคุณ!
Joakim Skoog

1
เหมือนกันกับสคริปต์ SSIS เพิ่มแผ่นงาน excel
SteveCav

@ JoakimSkoog ... ฉันมีปัญหานี้ในโครงการ. NET Standard (ไม่เคยแปลง) และยังคงต้องเพิ่มในการอ้างอิงด้วยตนเอง
ebol2000

1

มีปัญหานี้โดยใช้คำหลักแบบไดนามิกร่วมกับ Newtonsoft.json ในโครงการ. net 3.0

การแก้ไขคือการปล่อยไดนามิกทั้งหมดและใช้ JObject แทน:

จาก

dynamic locales = JObject.Parse(this.Locales);

ถึง

JObject locales = JObject.Parse(this.Locales);

0

มีปัญหาที่ทราบเกี่ยวกับข้อผิดพลาดของการสร้างที่ไม่ปรากฏในรายการข้อผิดพลาด ดูตัวอย่างเช่นhttps://github.com/dotnet/roslyn/issues/4567

หากต้องการแก้ไขในหน้าต่าง "รายการข้อผิดพลาด" ให้เลือกเมนูแบบเลื่อนลงทางด้านขวาของ "ข้อความ" และเลือก "Build + IntelliSense"


0

ฉันมีปัญหาที่คล้ายกันและสิ่งเดียวที่แก้ไขให้ฉันได้คือการอัพเกรดแพ็คเกจ NUnit ของฉันเป็นเวอร์ชันล่าสุด

โดยวิธีเมื่อคุณเปิดหน้าต่าง Nuget ตรวจสอบให้แน่ใจว่าคุณไม่ได้ลดระดับแพ็คเกจของคุณ (เมื่อฉันมีรุ่น 2.0.11 มันแสดงให้ฉันอัพเกรดเป็นรุ่น 2.0.9 ซึ่งจริง ๆ แล้วลดระดับ ... )

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