La construction de VS2015 échoue sans message d'erreur avec Dynamic

136

J'écrivais un test unitaire sur un morceau de code qui retournait JSON. Le type qu'il renvoie est un type anonyme, j'ai donc pensé que pour vérifier les valeurs dessus, je viens de convertir l'objet en a dynamicpour faire mes assertions.

Cependant, lorsque je fais cela, ma construction échoue mais je n'ai aucun message d'erreur. J'ai pu reproduire cela avec un code très simple dans un nouveau projet de test unitaire:

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

    dynamic asDynamic = obj;

    Assert.IsTrue(asDynamic.someValue);
}

Voir ci-dessous pour une capture d'écran de l'échec de la construction

build échouant

La construction réussit quand je commente l'assertion:

construire réussir sans affirmer

En revanche, j'ai exécuté le code suivant dans LinqPad 5 beta (qui utilise le compilateur Roslyn) et je n'ai eu aucun problème:

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

Vrai

Que se passe t-il ici? Étant donné que l'erreur ne s'affiche pas, je ne peux pas dire si j'utilise de dynamicmanière incorrecte, ou s'il ne trouve pas la surcharge à utiliser à IsTrue()cause de dynamic, ou s'il s'agit d'un bogue dans le compilateur (bien que je doute fortement de cela , Je n'ai aucune preuve qu'il y a un problème avec mon code).

En ce qui concerne le problème de surcharge, j'ai essayé Assert.IsTrue((bool)asDynamic.someValue);mais la construction échoue toujours, toujours pas de message d'erreur.

Selon le commentaire de @ RonBeyer, j'avais également essayé plus de casting comme ci-dessous en vain:

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

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

En y regardant de plus près, j'ai trouvé une erreur répertoriée dans la fenêtre Sortie:

c: ... \ DynamicBuildFailTest \ UnitTest1.cs (16,33,16,42): erreur CS0656: membre requis du compilateur manquant 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create'

D'accord, VS2013 est meilleur pour signaler les erreurs, je vais chercher en me basant sur celles-ci:

entrez la description de l'image ici

D'accord, l' ajout d'une référence à Microsoft.CSharp a corrigé l'erreur de construction , mais je vais laisser cette question ouverte car c'est probablement un problème avec VS2015 qui (dans mon esprit) devrait être résolu.

DLeh
la source
Êtes-vous sûr qu'il s'agit en fait d'un échec de compilation plutôt que d'un échec de liaison?
David W
Pouvez-vous essayer dynamic asDynamic = (dynamic)obj;? Ou juste dans l'assertion, commentez la dynamique et écrivez Assert.IsTrue(((dynamic)obj).someValue);.
Ron Beyer
@RonBeyer oui j'avais essayé les deux, pas de chance.
DLeh
Un de plus ... Assert.IsTrue((bool)asDynamic.someValue);?
Ron Beyer
1
J'ai rencontré le même problème dans VS2015 en essayant d'utiliser des méthodes de test dynamiques. La construction a échoué sans aucune erreur. Et après avoir ajouté la référence Microsoft.CSharp, la génération a réussi.
Sarath Rachuri

Réponses:

226

Il y a une erreur du compilateur, Visual Studio 2015 ne signale tout simplement pas l'erreur correctement. Cependant, Visual Studio 2013 fait:

Ceci est répondu ici: https://stackoverflow.com/a/13568247 :

En bref:

Ajoutez une référence à Microsoft.CSharp afin d'utiliser dynamiccomme ceci.

DLeh
la source
9
Ajoutez la référence à la Microsoft.CSharpdll même si elle using Microsoft.CSharp;ne lève pas d'erreur de compilation.
Barry Guvenkaya
45
Avec .NET Core, ajoutez plutôt le package NuGet Microsoft.CSharp.
Bart Verkoeijen
6
De même pour la bibliothèque de classes basée sur .Net Standard - ajoutez le package NuGet Microsoft.CSharp.
Hong
50

Comme deux personnes l'ont noté dans les commentaires, pour Net Core et NetStandard, ce problème est parfois résolu en ajoutant une référence NuGet à Microsoft.CSharp.

Nicholas Petersen
la source
3
Cela a résolu mon problème après la conversion d'un projet en .NET Standard, merci!
Joakim Skoog du
1
Idem avec un script SSIS ajoutant une feuille Excel.
SteveCav
@JoakimSkoog ... J'ai eu ce problème sur un projet .NET Standard (jamais converti) et j'ai encore dû ajouter une référence manuellement.
ebol2000
1

Eu ce problème en utilisant le mot-clé dynamique en combinaison avec Newtonsoft.json dans un projet .net 3.0.

Le correctif était de supprimer complètement la dynamique et d'utiliser JObject à la place:

de

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

à

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

Il existe un problème connu avec les erreurs de construction qui n'apparaissent pas dans la liste des erreurs. Voir, par exemple, https://github.com/dotnet/roslyn/issues/4567 .

Pour contourner ce problème, dans la fenêtre "Liste des erreurs", sélectionnez le menu déroulant à droite de "Messages" et sélectionnez "Construire + IntelliSense".

Neal Gafter
la source
0

J'ai eu un problème similaire et la seule chose qui me l'a résolu a été de mettre à niveau mon package NUnit vers la dernière version.

Au fait, lorsque vous ouvrez la fenêtre Nuget, assurez-vous que vous ne rétrogradez pas votre paquet (quand j'avais la version 2.0.11, cela m'a montré de passer à la version 2.0.9 qui est en fait une rétrogradation ...)

argent
la source