Czy C # 6.0 działa dla .NET 4.0?

275

Stworzyłem przykładowy projekt z dodatkami C # 6.0 - propagacja zerowa i inicjalizacja właściwości jako przykład, ustaw docelową wersję .NET 4.0 i to ... działa.

public class Cat
{
    public int TailLength { get; set; } = 4;

    public Cat Friend { get; set; }

    public string Mew() { return "Mew!"; }
}

class Program
{
    static void Main(string[] args)
    {
        var cat = new Cat {Friend = new Cat()};
        Console.WriteLine(cat?.Friend.Mew());
        Console.WriteLine(cat?.Friend?.Friend?.Mew() ?? "Null");
        Console.WriteLine(cat?.Friend?.Friend?.TailLength ?? 0);
    }
}

Czy to oznacza, że ​​mogę używać funkcji C # 6.0 dla mojego oprogramowania, które jest ukierunkowane na .NET 4.0? Czy są jakieś ograniczenia lub wady?

MajesticRa
źródło
7
Wersje .Net 2.0 - 3.5 używają CLR v2.0. Nowsze wersje używają CLR v4.0.
i3arnon
pamiętaj o tym, optymalizuj mądrze: dodajesz osobne sprawdzanie „zero” dla każdego takiego kota
Terence
2
Mój Boże. Pracuję nad WCF ukierunkowanym na wersję v4.6, aby „przypomnieć”, że serwer produkcyjny ma zostać uaktualniony dopiero w 2018 roku. Myślałem, że miesiąc pracy będzie wymagał kilku dni refaktoryzacji. Zakończono za pięć minut. Dziękuję, Microsoft! : D
Eric Wu,

Odpowiedzi:

286

Tak (głównie). C # 6.0 wymaga nowego kompilatora Roslyn, ale nowy kompilator może kompilować ukierunkowane na starsze wersje frameworka. Jest to ograniczone tylko do nowych funkcji, które nie wymagają wsparcia ze strony frameworka .

Na przykład, chociaż można użyć funkcji interpolacji ciągów w języku C # 6.0 we wcześniejszych wersjach .Net (ponieważ powoduje to wywołanie string.Format):

int i = 3;
string s = $"{i}";

Potrzebujesz .Net 4.6, aby używać go, IFormattableponieważ tylko nowa wersja frameworka dodaje System.FormattableString:

int i = 3;
IFormattable s = $"{i}";

Wspomniane przypadki nie potrzebują typów z frameworka do działania. Kompilator jest więc w stanie w pełni obsługiwać te funkcje w starszych wersjach frameworka.

i3arnon
źródło
31
W rzeczywistości nie potrzebujesz .Net 4.6, tylko kilka typów, które są w nim dodane. Możesz dodać je do starszych frameworków. Ten kod działa dobrze w .Net 4.0 i 3.5.
svick
10
Czy jest gdzieś lista, które funkcje C # 6 działają w .NET 4.0? Innym sposobem zadawania pytań byłoby: które nowe funkcje wymagają wsparcia z frameworka, a które nie?
Rubenisme,
1
@ Rubenisme Nie mogę wymyślić innego niż IFormattableinterpolacja łańcuchów.
i3arnon
2
Wydaje mi się, że możemy powiedzieć, że wszystkie cukry składniowe mogą być używane i kierowane do starszych wersji frameworka. czy można to powiedzieć?
mkb
4
@mkb tak. Cukier syntaktyczny to dokładnie te funkcje, które opierają się tylko na możliwościach kompilatora, a nie na ramowych.
i3arnon
52

Chcę się skupić na zrozumieniu Wikipedii i innych linków.

Kiedy Wikipedia mówi, że C # 6.0 jest z .NET Framework 4.6, oznacza to po prostu, że wersja produkcyjna kompilatora (msc.exe) będzie częścią wydania .NET Framework 4.6. Dzięki wielu celowaniu takie kompilatory mogą obsługiwać niższe wersje wydań .NET Framework. Oczywiście, odkąd Roslyn stała się projektem open source, kompilator jest teraz całkowicie indywidualnym komponentem.

Gdy coś odnosi się do wersji CLR 4.0.30319 (.0), tak naprawdę może to być .NET Framework 4. * (4.0, 4.0. *, 4.5, 4.5. *, 4.6, 4.6. *), Ponieważ wszystkie implementują Specyfikacja CLR wersja 4. Nie wspominając już o Xamarin / Mono, które implementują tę samą specyfikację CLR.

Strona MSDN nie jest jeszcze w pełni zaktualizowana, ale niektóre strony mają już .NET Framework 4.6 wymienione w sekcji Informacje o wersji.

Ogólnie rzecz biorąc, specyfikacje językowe (a także kompilator C #), specyfikacje CLR i wersje .NET Framework nie są ze sobą ściśle powiązane. Daje to programistom wystarczającą elastyczność, aby wykorzystywać nowe kompilatory do kierowania do starszych CLR i .NET Framework.

Lex Li
źródło
29

Tak, możesz używać nowszych kompilatorów dla starszych platform i uzyskać dostęp do nowych funkcji kompilatora (o ile te funkcje nie wymagają nowych typów wprowadzonych w .NET 4.6).

Innymi przykładami są metody z parametrami domyślnymi wprowadzone w C # 4.0 (.NET 4.0), ale można ich używać w projektach .NET 2.0 (C # 2.0) i .NET 3.5 (C # 3.0).

Możesz również używać metod rozszerzeń (wprowadzonych w C # 3.0) w .NET 2.0 lub .NET 3.0, jeśli wykonasz jedno małe obejście, aby uszczęśliwić kompilator, aby mógł znaleźć atrybut, który został wprowadzony w .NET 3.5.

Scott Chamberlain
źródło
1

Jeśli używasz skryptów budowlanych, pamiętaj o zmianie ścieżki do nowego programu budującego:

ustaw CPATH = C: \ Program Files (x86) \ MSBuild \ 14.0 \ Bin

[Rebuild.bat]

set CPATH=C:\Program Files (x86)\MSBuild\14.0\Bin
call nuget_restore.bat
"%CPATH%\msbuild" YourSolution.sln /t:Rebuild /p:Configuration=Release /fileLogger /flp:logfile=JustErrors.log;errorsonly /verbosity:minimal

if %errorlevel% neq 0 goto ERROR

REM call deploy Release  //Things like deploy files..
goto END

:ERROR
       echo ERROR: %errorlevel%
       pause

:END
oobe
źródło
1

Odpowiedź @oobe jest rzeczywiście ważna. Mógłbym zbudować moje rozwiązanie za pomocą pliku wsadowego dopiero po użyciu MSBuild.exe z C: \ Program Files (x86) \ MSBuild \ 14.0 \ Bin .

Suryakant Soni
źródło