Сборка 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, которая (на мой взгляд) должна быть решена.

DLeh
источник
Вы уверены, что это на самом деле ошибка компиляции, а не ссылка?
Дэвид Вт,
Ты можешь попробовать dynamic asDynamic = (dynamic)obj;? Или просто в утверждении закомментируйте динамику и напишите Assert.IsTrue(((dynamic)obj).someValue);.
Рон Бейер
@RonBeyer да, я тоже попробовал оба, но не удача.
DLeh
Еще один ... Assert.IsTrue((bool)asDynamic.someValue);?
Рон Бейер
1
Я столкнулся с той же проблемой в VS2015 при попытке использовать динамический в тестовых методах. Сборка не удалась без ошибок. И после добавления ссылки Microsoft.CSharp сборка прошла успешно.
Сарат Рахури

Ответы:

226

Произошла ошибка компилятора, Visual Studio 2015 просто не сообщает об ошибке должным образом. Тем не менее, Visual Studio 2013 делает:

Ответ здесь: https://stackoverflow.com/a/13568247 :

Коротко:

Добавьте ссылку на Microsoft.CSharp, чтобы использовать ее dynamicследующим образом.

DLeh
источник
9
Добавьте ссылку на Microsoft.CSharpDLL, даже если using Microsoft.CSharp;не выдает ошибку времени компиляции.
Барри Гувенькая
45
С .NET Core добавьте пакет NuGet Microsoft.CSharp.
Барт Verkoeijen
6
То же самое для библиотеки классов на основе .Net Standard - добавить пакет NuGet Microsoft.CSharp.
Гонконг
50

Как отметили два человека в комментариях, для Net Core и NetStandard эта проблема иногда решается добавлением ссылки NuGet Microsoft.CSharp.

Николас Петерсен
источник
3
Это решило мою проблему после преобразования проекта в .NET Standard, спасибо!
Йоаким Скуг
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, которая на самом деле понизила ...)

Серебряный
источник