Kompilacja VS2015 kończy się niepowodzeniem i nie ma komunikatu o błędzie w przypadku wersji dynamicznej

136

Pisałem test jednostkowy na fragmencie kodu, który zwrócił JSON. Typ, który zwraca, jest typem anonimowym, więc pomyślałem, że aby zweryfikować wartości, po prostu rzuciłem obiekt na a, dynamicaby wykonać moje asercje.

Jednak kiedy to robię, moja kompilacja kończy się niepowodzeniem, ale nie mam żadnych komunikatów o błędach. Udało mi się to odtworzyć za pomocą bardzo prostego kodu w nowym projekcie testów jednostkowych:

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

    dynamic asDynamic = obj;

    Assert.IsTrue(asDynamic.someValue);
}

Poniżej znajduje się zrzut ekranu przedstawiający niepowodzenie kompilacji

kompilacja kończy się niepowodzeniem

Kompilacja powiedzie się, gdy skomentuję to stwierdzenie:

budować bez potwierdzenia

Z drugiej strony uruchomiłem następujący kod w LinqPad 5 beta (który używa kompilatora Roslyn) i nie miałem żadnych problemów:

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

Prawdziwe

Co tu się dzieje? Ponieważ błąd się nie wyświetla, nie mogę stwierdzić, czy używamdynamic nieprawidłowo, czy nie mogę znaleźć przeciążenia do użycia z IsTrue()powodu dynamic, lub czy jest to błąd w kompilatorze (chociaż bardzo w to wątpię , Nie mam żadnych dowodów na to, że coś jest nie tak z moim kodem).

Jeśli chodzi o problem z przeciążeniem, próbowałem Assert.IsTrue((bool)asDynamic.someValue); ale kompilacja nadal się nie udaje, nadal nie ma komunikatu o błędzie.

Zgodnie z komentarzem @ RonBeyera, próbowałem też rzucić więcej, takich jak poniżej, ale bezskutecznie:

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

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

Po dokładniejszym zbadaniu stwierdziłem, że w oknie Wyjście wystąpił błąd:

c: ... \ DynamicBuildFailTest \ UnitTest1.cs (16,33,16,42): błąd CS0656: brak wymaganego elementu członkowskiego kompilatora „Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create”

Okej, VS2013 lepiej radzi sobie z raportowaniem błędów, wyszukam na podstawie tych:

wprowadź opis obrazu tutaj

Okay, dodanie odwołania do Microsoft.CSharp naprawiło błąd kompilacji , ale zostawię to pytanie otwarte, ponieważ prawdopodobnie jest to problem z VS2015, który (moim zdaniem) powinien zostać rozwiązany.

DLeh
źródło
Czy na pewno jest to błąd kompilacji, a nie błąd łącza?
David W
Możesz spróbować dynamic asDynamic = (dynamic)obj;? Lub po prostu w Asercji, skomentuj dynamikę i napisz Assert.IsTrue(((dynamic)obj).someValue);.
Ron Beyer
@RonBeyer tak, próbowałem też obu tych rozwiązań, niestety.
DLeh
Jeszcze jeden ... Assert.IsTrue((bool)asDynamic.someValue);?
Ron Beyer,
1
Napotkałem ten sam problem w VS2015, próbując użyć dynamiki w metodach testowych. Kompilacja nie powiodła się bez żadnych błędów. Po dodaniu odwołania Microsoft.CSharp kompilacja powiodła się.
Sarath Rachuri

Odpowiedzi:

226

Wystąpił błąd kompilatora, program Visual Studio 2015 po prostu nie zgłasza błędu poprawnie. Jednak Visual Studio 2013 robi:

Odpowiedź na to pytanie znajduje się tutaj: https://stackoverflow.com/a/13568247 :

W skrócie:

Dodaj odwołanie do Microsoft.CSharp, aby używać w dynamicten sposób.

DLeh
źródło
9
Dodaj odwołanie do Microsoft.CSharpdll, mimo że using Microsoft.CSharp;nie zgłasza błędu czasu kompilacji.
Barry Guvenkaya
45
Z .NET Rdzenia dodać pakiet Nuget Microsoft.CSharpzamiast.
Bart Verkoeijen
6
To samo dotyczy biblioteki klas opartej na platformie .Net Standard - dodaj pakiet NuGet Microsoft.CSharp.
Hong
50

Jak dwie osoby zauważyły ​​w komentarzach, w przypadku Net Core i NetStandard ten problem jest czasami naprawiany przez dodanie odwołania NuGet do Microsoft.CSharp.

Nicholas Petersen
źródło
3
To rozwiązało mój problem po konwersji projektu do .NET Standard, dziękuję!
Joakim Skoog,
1
Podobnie ze skryptem SSIS dodającym arkusz Excela.
SteveCav,
@JoakimSkoog ... Miałem ten problem w projekcie .NET Standard (nigdy nie konwertowano) i nadal musiałem ręcznie dodać odwołanie.
ebol2000
1

Wystąpił ten problem przy użyciu dynamicznego słowa kluczowego w połączeniu z Newtonsoft.json w projekcie .net 3.0.

Rozwiązaniem było całkowite porzucenie dynamiki i użycie JObject zamiast tego:

z

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

do

JObject locales = JObject.Parse(this.Locales);
Dan Ochiana
źródło
0

Istnieje znany problem polegający na tym, że błędy kompilacji nie pojawiają się na liście błędów. Zobacz na przykład https://github.com/dotnet/roslyn/issues/4567 .

Aby obejść ten problem, w oknie „Lista błędów” wybierz menu rozwijane po prawej stronie pozycji „Wiadomości” i wybierz opcję „Kompiluj + IntelliSense”.

Neal Gafter
źródło
0

Miałem podobny problem i jedyną rzeczą, która go rozwiązała, była aktualizacja mojego pakietu NUnit do najnowszej wersji.

Przy okazji, kiedy otworzysz okno Nuget, upewnij się, że nie obniżasz wersji swojego pakietu (kiedy miałem wersję 2.0.11, pokazało mi, że muszę zaktualizować do wersji 2.0.9, która faktycznie obniża ...)

srebro
źródło