Définitions de macro C # dans le préprocesseur

C # est-il capable de définir des macros comme dans le langage de programmation C avec des instructions de pré-processeur? Je voudrais simplifier la saisie régulière de certaines instructions répétitives telles que les suivantes:

Console.WriteLine("foo"); 

Non, C # ne supporte pas les macros de préprocesseur comme C. Visual Studio a des extraits . Les extraits de Visual Studio sont une fonctionnalité de l’EDI et sont développés dans l’éditeur plutôt que d’être remplacés dans le code lors de la compilation par un préprocesseur.

Vous pouvez utiliser un préprocesseur C (comme mcpp) et le ranger dans votre fichier .csproj. Ensuite, vous devez “créer une action” sur votre fichier source depuis Comstack to Preprocess ou ce que vous appelez. Ajoutez simplement BeforBuild à votre .csproj comme ceci:

       

Vous devrez peut-être modifier manuellement Comstackr en pré-traitement sur au moins un fichier (dans un éditeur de texte) – alors l’option “Pré-traitement” devrait être disponible pour la sélection dans Visual Studio.

Je sais que les macros sont fortement surexploitées et mal utilisées, mais les supprimer complètement est tout aussi grave, voire pire. Un exemple classique d’utilisation de macro serait NotifyPropertyChanged . Tout programmeur qui a dû réécrire ce code manuellement des milliers de fois sait combien il est douloureux sans macros.

Je l’utilise pour éviter Console.WriteLine(...) :

 public static void Cout(this ssortingng str, params object[] args) { Console.WriteLine(str, args); } 

et puis vous pouvez utiliser les éléments suivants:

 "line 1".Cout(); "This {0} is an {1}".Cout("sentence", "example"); 

c’est concis et gentil génial.

Bien que vous ne puissiez pas écrire de macros, quand il s’agit de simplifier des choses comme votre exemple, C # 6.0 offre désormais des utilisations statiques. Voici l’exemple donné par Martin Pernica sur son article Medium :

 using static System.Console; // Note the static keyword namespace CoolCSharp6Features { public class Program { public static int Main(ssortingng[] args) { WriteLine("Hellow World without Console class name prefix!"); return 0; } } } 

Il n’y a pas d’équivalent direct avec les macros de style C en C #, mais les méthodes statiques en inline – avec ou sans #if / #elseif / #else pragmas – sont les plus proches:

  ///  /// Prints a message when in debug mode ///  [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void Log(object message) { #if DEBUG Console.WriteLine(message); #endif } ///  /// Prints a formatted message when in debug mode ///  /// A composite format ssortingng /// An array of objects to write using format [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void Log(ssortingng format, params object[] args) { #if DEBUG Console.WriteLine(format, args); #endif } ///  /// Computes the square of a number ///  /// The value /// x * x [MethodImpl(MethodImplOptions.AggressiveInlining)] public static double Square(double x) { return x * x; } ///  /// Wipes a region of memory ///  /// The buffer [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ClearBuffer(ref byte[] buffer) { ClearBuffer(ref buffer, 0, buffer.Length); } ///  /// Wipes a region of memory ///  /// The buffer /// Start index /// Number of bytes to clear [MethodImpl(MethodImplOptions.AggressiveInlining)] public static unsafe void ClearBuffer(ref byte[] buffer, int offset, int length) { fixed(byte* ptrBuffer = &buffer[offset]) { for(int i = 0; i < length; ++i) { *(ptrBuffer + i) = 0; } } } 

Cela fonctionne parfaitement en tant que macro, mais présente un petit inconvénient: les méthodes marquées en inline d seront copiées dans la partie reflection de votre assemblage comme toute autre méthode "normale".

Heureusement, C # n’a pas de préprocesseur de style C / C ++ – seules les compilations conditionnelles et les pragmas (et peut-être quelque chose que je ne peux pas rappeler) sont pris en charge. Malheureusement, C # n’a pas de capacités de métaprogrammation (cela peut en fait se rapporter à votre question dans une certaine mesure).

Transformez la macro C en une méthode statique C # dans une classe.

Je vous suggère d’écrire une extension, quelque chose comme ci-dessous.

 public static class WriteToConsoleExtension { // Extension to all types public static void WriteToConsole(this object instance, ssortingng format, params object[] data) { Console.WriteLine(format, data); } } class Program { static void Main(ssortingng[] args) { Program p = new Program(); // Usage of extension p.WriteToConsole("Test {0}, {1}", DateTime.Now, 1); } } 

J’espère que ça aide (et pas trop tard :))

Étant donné que C # 7.0 prend using static charge l’ using static fonctions de directive using static et locales, vous n’avez pas besoin de macros de préprocesseur pour la plupart des cas.