77

C#は、プリプロセッサステートメントを使用してCプログラミング言語で行われるようにマクロを定義できますか?次のような特定の繰り返しステートメントの通常の入力を簡略化したいと思います。

Console.WriteLine("foo");
4

10 に答える 10

58

いいえ、C#はCのようなプリプロセッサマクロをサポートしていません。一方、VisualStudioにはスニペットがあります。Visual StudioのスニペットはIDEの機能であり、プリプロセッサによるコンパイル時にコードで置き換えられるのではなく、エディターで展開されます。

于 2009-04-02T12:14:04.460 に答える
50

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>

(テキスト エディターで) 少なくとも 1 つのファイルで [コンパイル] を [前処理] に手動で変更する必要がある場合があります。その後、Visual Studio で [前処理] オプションを選択できるようになります。

マクロが酷使され、誤用されていることは知っていますが、それらを完全に削除することは、悪くはないにしても同様に悪いことです。マクロの使用の典型的な例はNotifyPropertyChangedです。このコードを何千回も手作業で書き直さなければならなかったすべてのプログラマーは、マクロを使用しないことがどれほど苦痛であるかを知っています。

于 2013-03-29T13:00:42.167 に答える
33

私はこれを避けるために使用します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");

簡潔でちょっとファンキーです。

于 2012-09-07T15:47:02.163 に答える
13

マクロを作成することはできませんが、例のように単純化する場合、C# 6.0 では静的な使用法が提供されるようになりました。以下は、Martin Pernica が彼の Medium 記事で示した例です。

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;
    }
  }
}
于 2015-11-08T03:13:19.113 に答える
8

C# には C スタイルのマクロに直接相当するものはありませんが、/ /プラグマのinline有無にかかわらず、d 静的メソッドが最も近いものです。#if#elseif#else

        /// <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 とマークされたメソッドは、他の「通常の」メソッドと同様に、アセンブリのリフレクション部分にコピーされます。

于 2015-05-13T15:33:14.907 に答える
3

幸い、C#にはC / C ++スタイルのプリプロセッサはありません。条件付きコンパイルとプラグマ(およびおそらく思い出せないもの)のみがサポートされています。残念ながら、C#にはメタプログラミング機能がありません(これ実際にはある程度あなたの質問に関連している可能性があります)。

于 2009-04-02T12:15:17.920 に答える
1

C マクロをクラスの C# 静的メソッドに変換します。

于 2009-04-02T12:17:24.233 に答える
1

ラムダを使用する

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");
于 2021-03-27T18:49:05.920 に答える
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);
    }
}

これが役に立てば幸いです(手遅れではありません:))

于 2011-02-07T00:50:56.380 に答える