Определения макросов C# в препроцессоре
Это c# - уметь определять макросы, как это сделано в языке программирования C ++ с препроцессором заявления? Я хотел бы упростить регулярную типизацию некоторых повторяющихся утверждений, таких как:
Console.WriteLine("foo");
9 ответов:
нет, C# не поддерживает макросы препроцессора, такие как C. Visual Studio с другой стороны имеет фрагментов. Фрагменты Visual Studio являются особенностью среды IDE и расширяются в редакторе, а не заменяются в коде при компиляции препроцессором.
вы можете использовать препроцессор C (например, mcpp) и установить его в свой .файл csproj. Затем вы chnage "build action" на исходном файле от компиляции до предварительной обработки или как вы его называете. Просто добавьте 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>
возможно, Вам придется вручную изменить Compile для предварительной обработки хотя бы одного файла (в текстовом редакторе) - тогда опция "Preprocess" должна быть доступна для выбора в Visual Studio.
Я знаю что макросы сильно злоупотребляют и злоупотребляют, но их полное удаление одинаково плохо, если не хуже. Классическим примером использования макросов будет NotifyPropertyChanged. Каждый программист, которому приходилось переписывать этот код вручную тысячи раз, знает, как это больно без макросов.
Я использую это, чтобы избежать
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");
это лаконично и kindof фанки.
хотя вы не можете писать макросы, когда дело доходит до упрощения таких вещей, как ваш пример, C# 6.0 теперь предлагает статические использования. Вот пример Мартин Перница дал на его средняя статья:
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; } } }
в C# нет прямого эквивалента макросам C-стиля, но
inline
д статические методы - С или без#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 будет скопирован в отражающую часть вашей сборки, как и любой другой "нормальный" метод.
к счастью, C# не имеет препроцессора в стиле C / C++ - поддерживаются только условная компиляция и прагмы (и, возможно, что-то еще, что я не могу вспомнить). К сожалению, C# не имеет возможности метапрограммирования (это мая на самом деле относятся к вашему вопросу в какой-то степени).
Я бы предложил вам написать расширение, что-то вроде ниже.
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); } }
надеюсь, это поможет (и не слишком поздно :))
Так как C# 7.0 поддерживает и локальные функции в большинстве случаев вам не нужны макросы препроцессора.