A construção do VS2015 falha com nenhuma mensagem de erro com Dynamic

136

Eu estava escrevendo um teste de unidade em um pedaço de código que retornou JSON. O tipo que ele retorna é um tipo anônimo, então pensei em verificar os valores nele. Acabei de converter o objeto em a dynamicpara fazer minhas afirmações.

No entanto, quando faço isso, minha compilação falha, mas não tenho nenhuma mensagem de erro. Consegui reproduzir isso com um código muito simples em um novo projeto de teste de unidade:

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

    dynamic asDynamic = obj;

    Assert.IsTrue(asDynamic.someValue);
}

Veja abaixo uma captura de tela da compilação com falha

falha na construção

A compilação é bem-sucedida quando eu comento a asserção:

construir com êxito sem afirmar

Por outro lado, executei o seguinte código no LinqPad 5 beta (que usa o compilador Roslyn) e não tive problemas:

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

Verdade

O que está acontecendo aqui? Como o erro não está aparecendo, não sei dizer se estou usando dynamicincorretamente ou se não consigo encontrar a sobrecarga a ser usada IsTrue()devido a dynamic, ou se é um bug no compilador (embora eu duvide muito disso , Não tenho nenhuma evidência de que haja algo errado com meu código).

Em relação ao problema de sobrecarga, tentei, Assert.IsTrue((bool)asDynamic.someValue);mas a compilação ainda falha, ainda não há mensagem de erro.

Pelo comentário do @ RonBeyer, eu também havia tentado mais transmissões, como as abaixo, sem sucesso:

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

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

Após uma inspeção mais detalhada, descobri que havia um erro listado na janela Saída:

c: ... \ DynamicBuildFailTest \ UnitTest1.cs (16,33,16,42): erro CS0656: Membro necessário do compilador ausente 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create'

Ok, o VS2013 é melhor em relatar os erros, procurarei com base naqueles:

insira a descrição da imagem aqui

Ok, a adição de uma referência ao Microsoft.CSharp corrigiu o erro de compilação , mas deixarei esta pergunta em aberto porque é presumivelmente um problema no VS2015 que (em minha mente) deve ser resolvido.

DLeh
fonte
Tem certeza de que é realmente uma falha de compilação, e não uma falha de link?
David W
Você pode tentar dynamic asDynamic = (dynamic)obj;? Ou apenas na asserção, comente a dinâmica e escreva Assert.IsTrue(((dynamic)obj).someValue);.
Ron Beyer
@ RonBeyer sim, eu tinha tentado os dois também, não sorte.
DLeh
Mais um ... Assert.IsTrue((bool)asDynamic.someValue);?
Ron Beyer
1
Eu enfrentei o mesmo problema no VS2015 ao tentar usar dinâmico nos métodos de teste. A construção falhou sem erros. E depois de adicionar a referência Microsoft.CSharp, a compilação foi bem-sucedida.
Sarath Rachuri

Respostas:

226

Há um erro do compilador, o Visual Studio 2015 simplesmente não relata o erro corretamente. No entanto, o Visual Studio 2013 faz:

Isso é respondido aqui: https://stackoverflow.com/a/13568247 :

Em resumo:

Adicione uma referência ao Microsoft.CSharp para usar dynamicdessa maneira.

DLeh
fonte
9
Adicione a referência à Microsoft.CSharpDLL, mesmo que using Microsoft.CSharp;não esteja gerando um erro de tempo de compilação.
Barry Guvenkaya
45
Com o .NET Core, adicione o pacote NuGet Microsoft.CSharp.
Bart Verkoeijen
6
O mesmo para a biblioteca de classes baseada no .Net Standard - adicione o pacote NuGet Microsoft.CSharp.
Hong
49

Como duas pessoas observaram nos comentários, para o Net Core e o NetStandard, esse problema às vezes é corrigido adicionando-se uma referência ao NuGet Microsoft.CSharp.

Nicholas Petersen
fonte
3
Isso resolveu meu problema depois de converter um projeto para o .NET Standard, obrigado!
Joakim Skoog
1
O mesmo acontece com um script SSIS que adiciona uma planilha do Excel.
SteveCav
@JoakimSkoog ... Eu tive esse problema em um projeto .NET Standard (nunca convertido) e ainda tinha que adicionar uma referência manualmente.
ebol2000
1

Teve esse problema usando a palavra-chave dinâmica em combinação com Newtonsoft.json em um projeto .net 3.0.

A correção foi abandonar a dinâmica completamente e usar JObject:

de

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

para

JObject locales = JObject.Parse(this.Locales);
Dan Ochiana
fonte
0

Há um problema conhecido com erros de compilação que não aparecem na lista de erros. Consulte, por exemplo, https://github.com/dotnet/roslyn/issues/4567 .

Para contornar isso, na janela "Lista de erros", selecione o menu suspenso à direita de "Mensagens" e selecione "Build + IntelliSense".

Neal Gafter
fonte
0

Eu tive um problema semelhante e a única coisa que me resolveu foi atualizar meu pacote NUnit para a versão mais recente.

A propósito, quando você abre a janela do Nuget, verifique se você não está desclassificando seu pacote (quando eu tinha a versão 2.0.11, ele me mostrou a atualização para a versão 2.0.9, que na verdade está desclassificando ...)

prata
fonte