预处理器中的C#宏定义

时间:2009-04-02 12:12:50

标签: c# macros c-preprocessor

C#能否像使用预处理器语句在C编程语言中那样定义宏?我想简化某些重复语句的常规输入,如下所示:

Console.WriteLine("foo");

11 个答案:

答案 0 :(得分:44)

不,C#不支持像C这样的预处理器宏。另一方面,Visual Studio有snippets。 Visual Studio的代码片段是IDE的一个功能,在编辑器中进行了扩展,而不是在预处理器的编译代码中替换。

答案 1 :(得分:32)

您可以使用C预处理器(如mcpp)并将其安装到.csproj文件中。然后,您可以在源文件中编译“构建操作”,从“编译”到“预处理”或您调用的任何内容。 只需将 BeforBuild 添加到.csproj中,如下所示:

  <Target Name="BeforeBuild" Inputs="@(Preprocess)" Outputs="@(Preprocess->'%(Filename)_P.cs')">
<Exec Command="..\Bin\cpp.exe @(Preprocess) -P -o %(RelativeDir)%(Filename)_P.cs" />
<CreateItem Include="@(Preprocess->'%(RelativeDir)%(Filename)_P.cs')">
  <Output TaskParameter="Include" ItemName="Compile" />
</CreateItem>

您可能必须在至少一个文件(在文本编辑器中)手动更改编译为预处理 - 然后在Visual Studio中可以选择“预处理”选项。

我知道宏被严重过度使用和误用,但是如果不是更糟的话,将它们完全删除也同样糟糕。宏使用的典型示例是 NotifyPropertyChanged 。每个必须手动重写这段代码的程序员都知道没有宏会有多痛苦。

答案 2 :(得分:26)

我用它来避免Console.WriteLine(...)

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

然后您可以使用以下内容:

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

它简洁而又时髦。

答案 3 :(得分:9)

虽然你不能编写宏,但在简化你的例子之类的东西时,C#6.0现在提供静态使用。这是Martin Pernica在his Medium article上给出的例子:

using static System.Console; // Note the static keyword

namespace CoolCSharp6Features
{
  public class Program
  {
    public static int Main(string[] args)
    {
      WriteLine("Hellow World without Console class name prefix!");

      return 0;
    }
  }
}

答案 4 :(得分:4)

在C#中没有与C风格的宏直接等价,但inline d静态方法 - 有或没有#if / #elseif / #else pragma - 是最近的你可以得到:

        /// <summary>
        /// Prints a message when in debug mode
        /// </summary>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static unsafe void Log(object message) {
#if DEBUG
            Console.WriteLine(message);
#endif
        }

        /// <summary>
        /// Prints a formatted message when in debug mode
        /// </summary>
        /// <param name="format">A composite format string</param>
        /// <param name="args">An array of objects to write using format</param>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static unsafe void Log(string format, params object[] args) {
#if DEBUG
            Console.WriteLine(format, args);
#endif
        }

        /// <summary>
        /// Computes the square of a number
        /// </summary>
        /// <param name="x">The value</param>
        /// <returns>x * x</returns>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static double Square(double x) {
            return x * x;
        }

        /// <summary>
        /// Wipes a region of memory
        /// </summary>
        /// <param name="buffer">The buffer</param>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public static unsafe void ClearBuffer(ref byte[] buffer) {
            ClearBuffer(ref buffer, 0, buffer.Length);
        }

        /// <summary>
        /// Wipes a region of memory
        /// </summary>
        /// <param name="buffer">The buffer</param>
        /// <param name="offset">Start index</param>
        /// <param name="length">Number of bytes to clear</param>
        [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;
                }
            }
        }

这非常适合用作宏,但有一点缺点:标记为inline d的方法将被复制到程序集的反射部分,就像其他任何&#34;正常&#34;方法

答案 5 :(得分:2)

幸运的是,C#没有C / C ++风格的预处理器 - 只支持条件编译和编译指示(可能还有其他我不记得的东西)。不幸的是,C#没有元编程功能(这个可能在某种程度上与你的问题有关)。

答案 6 :(得分:1)

将C宏转换为类中的C#静态方法。

答案 7 :(得分:1)

我建议您编写扩展名,如下所示。

public static class WriteToConsoleExtension
{
   // Extension to all types
   public static void WriteToConsole(this object instance, 
                                     string format, 
                                     params object[] data)
   {
       Console.WriteLine(format, data);
   }
}

class Program
{
    static void Main(string[] args)
    {
        Program p = new Program();
        // Usage of extension
        p.WriteToConsole("Test {0}, {1}", DateTime.Now, 1);
    }
}

希望这会有所帮助(而且不会太晚:))

答案 8 :(得分:0)

由于C#7.0支持using static指令和Local functions,因此在大多数情况下不需要预处理器宏。

答案 9 :(得分:0)

使用 lambdas

void print(string x) => Trace.WriteLine(x);
void println(string x) => Console.WriteLine(x);
void start(string x) => Process.Start(x);

void done() => Trace.WriteLine("Done");
void hey() => Console.WriteLine("hey");

答案 10 :(得分:-2)

我将创建一个名为C#macros的C#宏编译器。

进度为here