Benutzer mit den meisten Antworten
Gemeinsame Präprozessor-Direktiven

Frage
-
Ich hahe eine Solution, in der sich ein ASP.NET und ein WinForms Projektbefinden, beides C#. Beide sollen in Abhängikeit von bestimmten#define's kompiliert werden, so dass sie nachher zusammen passen. EineÄnderung an einer zentralen Stelle soll sich konsistent auf beideauswirken. So wie man das in C/C++ per #include xyz.h machen würde.Jetzt ist die Frage, wo diese zentrale Stelle ist?TIA,Hajü
Antworten
-
Hallo Hajü,
die gibt es in der Form nicht.
#define gilt nur für die Quelldatei in der sie definiert wird.
Zudem kann man je Projekt über Erstellen, Symbole für bedingte Kompilierung Direktiven für alle Dateien eines Projekts festlegen.
(und dies kann man für alle Konfigurationen oder auch nur einzelne tun).
Für eine Projektmappe (Solution) übergreifende Einträge gibt es nicht, da eine Projektmappe nur eine Zusammenfassung von Projekten darstellt.Gruß Elmar
- Als Antwort markiert Hans-J. Ude Sonntag, 20. Mai 2012 13:52
-
Hallo Hajü,
Das kannst Du m.E. nur über MSBuild erreichen, und zwar über
/p:DefineConstants=<DEFINE_SYMBOL>
Das Gute daran, ist dass die so definierten "Symbole für bedingte Kompilierung" die in den einzelnen csproj-Dateien definierten Symbole überschreiben. Ein Beispiel für ein MSBuild-Skript, welches das Solution-Build ersetzt, findest Du hier.
Gruß
Marcel- Als Antwort markiert Hans-J. Ude Sonntag, 20. Mai 2012 13:52
Alle Antworten
-
Hallo Hajü,
die gibt es in der Form nicht.
#define gilt nur für die Quelldatei in der sie definiert wird.
Zudem kann man je Projekt über Erstellen, Symbole für bedingte Kompilierung Direktiven für alle Dateien eines Projekts festlegen.
(und dies kann man für alle Konfigurationen oder auch nur einzelne tun).
Für eine Projektmappe (Solution) übergreifende Einträge gibt es nicht, da eine Projektmappe nur eine Zusammenfassung von Projekten darstellt.Gruß Elmar
- Als Antwort markiert Hans-J. Ude Sonntag, 20. Mai 2012 13:52
-
Hallo Hajü,
Das kannst Du m.E. nur über MSBuild erreichen, und zwar über
/p:DefineConstants=<DEFINE_SYMBOL>
Das Gute daran, ist dass die so definierten "Symbole für bedingte Kompilierung" die in den einzelnen csproj-Dateien definierten Symbole überschreiben. Ein Beispiel für ein MSBuild-Skript, welches das Solution-Build ersetzt, findest Du hier.
Gruß
Marcel- Als Antwort markiert Hans-J. Ude Sonntag, 20. Mai 2012 13:52
-
Hallo Marcel,
zum gleichen Resultat käme man über mehrere Build-Konfigurationen.
Was vermutlich günstiger ist, da sich i. a. weitere Angaben ändern, wie z. B. Ausgabepfade.
Siehe auch den letzten Absatz im verlinkten Blog ArtikelGruß Elmar
-
Hallo Elmar,
Die Idee mit den mehrfachen Build-Konfigurationen finde ich gut. Wir beziehen uns auf den selben Autor, Sayed Ibrahim Hashimi, und auf dieselbe Technologie: MSBuild. Es gibt hier verschiedene Ansätze, und jeder Ansatz hat selbstredend seine Vor- und Nachteile. DefineConstants kann natürlich sowohl von der Befehlszeile als auch innerhalb des MSBuild-Skripts gesetzt werden, wichtig für mich war die Feststellung, dass es außerhalb der visuellen Projekt-Properties von Visual Studio eine Möglichkeit gibt, den Build von mehreren Projekten auf einfache Weise zu steuern. Auch Ausgabepfade können im MSBuild-Projekt in Abhängigkeit von Konstanten/Bedingungen gesetzt werden.
Für die Leser unsers Threads erlaube ich mir noch zwei kleine Dokumentations-Hinweise zum Schluss (falls einer mal Lust auf mehr MSBuild hat):
1. Thorsten Hans - MSBuild – Ein Überblick.
2. Sayed Ibrahim Hashimi & William Bartholomew - Inside the Microsoft Build Engine: Using MSBuild and Team Foundation Build (2nd ed.), Microsoft Press 2010.Viele Grüße
Marcel -
Danke für eure Antworten, auch an Elmar. Also. ich finde das schade dass das #include Konzept über Bord geflogen ist. Weiß jemand warum, das war doch so schön einfach und variabel? Die Erstzlösung finde ich etwas umständlich. Wobei bei mir das WinForms Projekt eh nur in der Entwicklungsphase als Kommunikationspartner zum Testen des ASP Projektes dient und früher oder später sowieso rausfliegt.
Hajü
-
Hallo Hajü,
naja, einfach nur solange wie alles glatt läuft...
Wenn man dann die Testmatrix für solchen Code betrachtet, ist schon nicht mehr so einfach.
Und ohne diese hat es der Compiler leichter, z. B. Eric Lippert dazu:
http://blogs.msdn.com/b/ericlippert/archive/2010/02/04/how-many-passes.aspx
In einer Objekt-orientierten Umgebung sollte man es nicht brauchen, auch wenn es Grenzfälle gibt -
z. B. bei gemeinsamen Code für WPF / Silverlight oder Windows / Mono.Gruß Elmar
-
Hallo Hajü
Dies war ein ein wesentliche Entscheidung im Sprachkonzept!
Der Verzicht auf #include-Dateien (pus div preprocessor)
ist IMHO sehr positiv zu werten. Lies folgende Blogs:
why doesn’t C# need header files?
http://blogs.msdn.com/b/ericlippert/archive/2010/02/04/how-many-passes.aspxWhy doesn't C# support #define macros?
http://blogs.msdn.com/b/csharpfaq/archive/2004/03/09/why-doesn-t-c-support-define-macros.aspx
C++
Header files and the preprocessor - Can't Live With 'em, Can't Live Without 'em
http://blogs.msdn.com/b/vcblog/archive/2007/04/19/header-files-and-the-preprocessor-can-t-live-with-em-can-t-live-without-em.aspxStop writing header files
http://blogs.msdn.com/b/devdev/archive/2005/08/19/453891.aspx
PS
evtl. eine Art Teilersatz wäre uU noch mit 'partial' machbar. -
Am 20.05.2012 16:59, schrieb Thomas Scheidegger Dev:> Der Verzicht auf #include-Dateien (pus div preprocessor)> ist IMHO sehr positiv zu werten. Lies folgende Blogs:Das ist alles diskutierbar. Ich glaube bei der Definition von C++ wardie Abwärtskompatibilität zu C ein wesentlicher Faktor, während bei C#die OOP im Vordergrund stand. Und, wie Elmar sagte, es gibt immerGrenzfälle.Hajü
-
Hallo Hajü,
C# ist trotz dem großen C am Anfang keine Fortführung von C++, auch wenn einiges daran erinnert. C# lebt in einem .NET-Biotop, dem die common language infrastructure zugrunde liegt. Es gehört zur Philosophie von C#, Abhängigkeiten zwischen Anwendungen auf der Symbolebene und nicht auf der Code-Ebene aufzulösen. Eines der Gründe dafür ist es, Barrieren zwischen Anwendungen aufzuheben, die in verschiedenen .NET-Sprachen geschrieben werden. Aus der C#-Spezifikation:
The program does not use #include to import program text. Dependencies among programs are
handled symbolically rather than textually. This approach eliminates barriers between applications
written using multiple languages. For example, the Console class need not be written in C#.Es gibt wie immer ein für und wider, in den meisten Fällen dürfte man mit #if #else #endif bzw. mit ConditionalAttribute weiterkommen. Sonst bleibt noch die Wiederverwendbarkeit auf Symbolebene (IL-Ebene).
Gruß
Marcel