Is C# able to define macros as is done in the C programming language with pre-processor statements? I would like to simplify regular typing of certain repeating statements such as the following:
Console.WriteLine("foo");
No, C# does not support preprocessor macros like C. Visual Studio on the other hand has snippets. Visual Studio's snippets are a feature of the IDE and are expanded in the editor rather than replaced in the code on compilation by a preprocessor.
#if/#elseif/#else
pragmas when with some simple macros one could emit the proper code for each target in an efficient/elegant and maintainable way. In short, C style macros are very helpful when you have to include code that simply will not compile on some targets.
Aug 29, 2013 at 22:42
#ifdefs
surrounding large blocks of code is good. It's not. I'm saying that judicial use of #define MACRO(x,y)
embedded within #ifdef PLATFORM1 #elif PLATFORM2 ...
can be useful in limited cases as a tool in the toolbox. Perhaps you disagree with this as well -- after doing a google search in defense of the preprocessor seems most of the world does as well. But I did come across this gem.
Sep 4, 2013 at 14:29
You can use a C preprocessor (like mcpp) and rig it into your .csproj file. Then you chnage "build action" on your source file from Compile to Preprocess or whatever you call it. Just add BeforBuild to your .csproj like this:
<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>
You may have to manually change Compile to Preprocess on at least one file (in a text editor) - then the "Preprocess" option should be available for selection in Visual Studio.
I know that macros are heavily overused and misused but removing them completely is equally bad if not worse. A classic example of macro usage would be NotifyPropertyChanged. Every programmer who had to rewrite this code by hand thousands of times knows how painful it is without macros.
MyCommon.targets
be just wrong? There are just some things that CPP can do that the language makes incredibly difficult. IMO, it is worse that the developer has to actually manually stringify an argument name when writing throw new ArgumentNullException("argumentName");
. Code contracts was supposed to solve that, but it requires an IL rewriter bolted on using .targets
, should be no worse to bolt on a CPP call.
I use this to avoid Console.WriteLine(...)
:
public static void Cout(this string str, params object[] args) {
Console.WriteLine(str, args);
}
and then you can use the following:
"line 1".Cout();
"This {0} is an {1}".Cout("sentence", "example");
it's concise and kindof funky.
Console.WriteLine(...)
(which is pretty long to have to type frequently). You could write your own method to do this but using a string extension is a little more elegant IMHO.
Aug 26, 2013 at 3:34
While you can't write macros, when it comes to simplifying things like your example, C# 6.0 now offers static usings. Here's the example Martin Pernica gave on 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;
}
}
}
There is no direct equivalent to C-style macros in C#, but inline
d static methods - with or without #if
/#elseif
/#else
pragmas - is the closest you can get:
/// <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;
}
}
}
This works perfectly as a macro, but comes with a little drawback: Methods marked as inline
d will be copied to the reflection part of your assembly like any other "normal" method.
[ConditionalAttribute("DEBUG")]
on those methods to achieve the same effect as the #if
s?
Luckily, C# has no C/C++-style preprocessor - only conditional compilation and pragmas (and possibly something else I cannot recall) are supported. Unfortunatelly, C# has no metaprogramming capabilities (this may actually relate to your question to some extent).
quit
variable. Once nested statements come into place, code gets hard to read and maintain. PHP has the break 2..n;
statement, C# doesn't. However, C# has enough LINQ extensions to actually not use nested loops in many cases, making the code readable in a different way - which I honestly prefer.
Jul 10, 2017 at 13:08
Turn the C Macro into a C# static method in a class.
I would suggest you to write extension, something like below.
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);
}
}
Hope this helps (and not too late :) )
ValidateUrl(this string)
- Something which by now I prefer in a class, as this both tends to bloat intellisense (especially with this object
) and makes finding such methods obscure sometimes. Having Validate.Url(string)
doesn't blow up the code and is evidently easy for others to find and utilize.
Jul 10, 2017 at 13:13
Use 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");
cw
in Visual Studio and press Tab.Console.WriteLine
toWriteLine
after addingusing static System.Console;
at the top of a source file.