Jest kilka pomniejszych miejsc, w których kod mojego projektu mógłby zostać drastycznie ulepszony, gdyby docelowa platforma była nowszą wersją. Chciałbym móc lepiej wykorzystać kompilację warunkową w C #, aby przełączyć je w razie potrzeby.
Coś jak:
#if NET40
using FooXX = Foo40;
#elif NET35
using FooXX = Foo35;
#else NET20
using FooXX = Foo20;
#endif
Czy któryś z tych symboli jest bezpłatny? Czy muszę wstrzykiwać te symbole w ramach konfiguracji projektu? Wydaje się to łatwe, ponieważ wiem, który framework jest przeznaczony dla MSBuild.
/p:DefineConstants="NET40"
Jak ludzie radzą sobie z tą sytuacją? Czy tworzysz różne konfiguracje? Czy przekazujesz stałe za pomocą wiersza poleceń?
Odpowiedzi:
Jednym z najlepszych sposobów osiągnięcia tego jest utworzenie różnych konfiguracji kompilacji w projekcie:
I w jednej z domyślnych konfiguracji:
Który ustawiłby wartość domyślną, gdyby nie została zdefiniowana nigdzie indziej. W powyższym przypadku OutputPath da ci oddzielny zestaw za każdym razem, gdy budujesz każdą wersję.
Następnie utwórz cel AfterBuild, aby skompilować różne wersje:
Ten przykład przekompiluje cały projekt ze zmienną Framework ustawioną na NET20 po pierwszej kompilacji (kompilując oba i zakładając, że pierwsza kompilacja była domyślną NET35 z góry). Każda kompilacja będzie miała poprawnie ustawione wartości warunkowe.
W ten sposób możesz nawet wykluczyć niektóre pliki w pliku projektu, jeśli nie chcesz #ifdef plików:
a nawet referencje
źródło
Alternatywą, która działa dla mnie do tej pory, jest dodanie do pliku projektu:
Przyjmuje wartość właściwości TargetFrameworkVersion, która podobnie jak „v3.5” zastępuje „v” i „”. aby uzyskać „NET35” (używając nowej funkcji Property Functions ). Następnie usuwa wszelkie istniejące wartości „NETxx” i dodaje je na końcu właściwości DefinedConstants. Być może uda się to usprawnić, ale nie mam czasu na zabawę.
Patrząc na kartę Kompilacja we właściwościach projektu w VS, zobaczysz wynikową wartość w sekcji symboli kompilacji warunkowej. Zmiana docelowej wersji platformy na karcie Aplikacja powoduje następnie automatyczną zmianę symbolu. Następnie można używać
#if NETxx
dyrektyw preprocesora w zwykły sposób. Zmiana projektu w VS nie powoduje utraty niestandardowej PropertyGroup.Zauważ, że to nie wydaje się dawać niczego innego dla opcji docelowych Profilu Klienta, ale nie jest to dla mnie problem.
źródło
Miałem problemy z tymi rozwiązaniami, być może dlatego, że moje początkowe stałe zostały wstępnie zbudowane przez te właściwości.
Visual Studio 2010 również zwrócił błąd z powodu średników, twierdząc, że są to niedozwolone znaki. Komunikat o błędzie dał mi wskazówkę, ponieważ mogłem zobaczyć wstępnie zbudowane stałe oddzielone przecinkami, po których ostatecznie występuje mój „nielegalny” średnik. Po ponownym sformatowaniu i zmasowaniu udało mi się znaleźć rozwiązanie, które działa dla mnie.
Chciałbym opublikować zrzut ekranu okna dialogowego Zaawansowane ustawienia kompilatora (otwieranego przez kliknięcie przycisku „Zaawansowane opcje kompilacji ...” na karcie Kompiluj projektu). Ale jako nowy użytkownik brakuje mi przedstawiciela, aby to zrobić. Gdybyś mógł zobaczyć zrzut ekranu, zobaczyłbyś niestandardowe stałe wypełniane automatycznie przez grupę właściwości, a następnie powiedziałbyś: „Muszę coś dla mnie przynieść”.
EDYCJA: Mam tego przedstawiciela zaskakująco szybko ... Dzięki! Oto ten zrzut ekranu:
źródło
Zacznij od wyczyszczenia stałych:
Następnie zbuduj swoje debugowanie, śledzenie i inne stałe, takie jak:
Na koniec zbuduj stałe ramowe:
Myślę, że to podejście jest bardzo czytelne i zrozumiałe.
źródło
W pliku .csproj, po istniejącej
<DefineConstants>DEBUG;TRACE</DefineConstants>
linii, dodaj to:Zrób to dla konfiguracji kompilacji debugowania i wydania. Następnie użyj w swoim kodzie:
źródło
@Azarien, twoja odpowiedź może być połączona z odpowiedzią Jeremy'ego, aby zachować ją w jednym miejscu, zamiast Debugowanie | Wydanie itp.
Dla mnie połączenie obu odmian działa najlepiej, tj. Włączanie warunków w kodzie za pomocą #if NETXX, a także tworzenie za jednym razem różnych wersji frameworka.
Mam te w moim pliku .csproj:
aw tarczach:
źródło
Jeśli korzystasz z systemu kompilacji .NET Core, możesz użyć jego wstępnie zdefiniowanych symboli (które w rzeczywistości pasują do Twojego przykładu i nie wymagają żadnych zmian
.csproj
!):Lista predefiniowanych symboli jest udokumentowana w Developing Libraries with Cross Platform Tools and #if (C # Reference) :
źródło