<p>While the C# spec does include a pre-processor and basic directives (#define, #if, etc), the language does not have the same flexible pre-processor found in languages such as C/C++. I believe the lack of such a flexible pre-processor was a design decision made by Anders Hejlsberg (although, unfortunately, I can't find reference to this now). From experience, this is certainly a good decision, as there were some really terrible un-maintainable macros created back when I was doing a lot of C/C++. </p>

<p>That said, there are a number of scenarios where I could find a slightly more flexible pre-processor to be useful. Code such as the following could be improved by some simple pre-processor directives:</p>

<pre><code>public string MyProperty
{
  get { return _myProperty; }
  set
  {
    if (value != _myProperty)
    {
      _myProperty = value;
      NotifyPropertyChanged("MyProperty");
      // This line above could be improved by replacing the literal string with
      // a pre-processor directive like "#Property", which could be translated
      // to the string value "MyProperty" This new notify call would be as follows:
      // NotifyPropertyChanged(#Property);
    }
  }
}
</code></pre>

<p>Would it be a good idea to write a pre-processor to handle extremely simple cases like this? Steve McConnell wrote in <a href="https://rads.stackoverflow.com/amzn/click/com/0735619670" rel="nofollow noreferrer" rel="nofollow noreferrer">Code Complete</a> (p208):</p>

<blockquote>
  <p><em>Write your own preprocessor</em>    If a language doesn't include a preprocessor, it's fairly easy to write one...</p>
</blockquote>

<p>I am torn. It was a design decision to leave such a flexible pre-processor out of C#. However, an author I highly respect mentions it may be ok in some circumstances.</p>

<p><strong>Should I build a C# pre-processor? Is there one available that does the simple things I want to do?</strong></p>

[{'answer_id': 37249, 'author': 'John Millikin', 'author_id': 3560, 'author_profile': 'https://Stackoverflow.com/users/3560', 'pm_score': 3, 'selected': False, 'text': '<blockquote>\n  <p>Should I build a C# pre-processor? Is there one available that does the simple things I want to do?</p>\n</blockquote>\n\n<p>You can always use the C pre-processor -- C# is close enough, syntax-wise. M4 is also an option.</p>\n'}, {'answer_id': 37260, 'author': 'Matt Hamilton', 'author_id': 615, 'author_profile': 'https://Stackoverflow.com/users/615', 'pm_score': 5, 'selected': True, 'text': '<p>Consider taking a look at an aspect-oriented solution like <a href="http://www.postsharp.org/" rel="noreferrer">PostSharp</a>, which injects code after the fact based on custom attributes. It\'s the opposite of a precompiler but can give you the sort of functionality you\'re looking for (PropertyChanged notifications etc).</p>\n'}, {'answer_id': 37268, 'author': 'billpg', 'author_id': 3568, 'author_profile': 'https://Stackoverflow.com/users/3568', 'pm_score': 0, 'selected': False, 'text': "<p>If I were designing the next version of C#, I'd think about each function having an automatically included local variable holding the name of the class and the name of the function. In most cases, the compiler's optimizer would take it out.</p>\n\n<p>I'm not sure there's much of a demand for that sort of thing though.</p>\n"}, {'answer_id': 37302, 'author': 'Jorge Córdoba', 'author_id': 2695, 'author_profile': 'https://Stackoverflow.com/users/2695', 'pm_score': 2, 'selected': False, 'text': '<p>I know a lot of people think short code equals elegant code but that isn\'t true.</p>\n\n<p>The example you propose is perfectly solved in code, as you have shown so, what do you need a preprocessor directive to? You don\'t want to "preprocess" your code, you want the compiler to insert some code for you in your properties. It\'s common code but that\'s not the purpose of the preprocessor.</p>\n\n<p>With your example, Where do you put the limit? Clearly that satisfies an observer pattern and there\'s no doubt that will be useful but there are a lot of things that would be useful that are actually done because code provides <strong>flexibility</strong> where as the preprocessor does not. If you try to implement common patterns through preprocessor directives you\'ll end with a preprocessor which needs to be as powerful as the language itself. If you want to <strong>process your code in a different way the use a preprocessor directive</strong> but if you just want a code snippet then find another way because the preprocessor wasn\'t meant to do that.</p>\n'}, {'answer_id': 37308, 'author': 'Brad Leach', 'author_id': 708, 'author_profile': 'https://Stackoverflow.com/users/708', 'pm_score': 0, 'selected': False, 'text': '<blockquote>\n  <p>@Jorge wrote: If you want to process your code in a different way the use a preprocessor directive but if you just want a code snippet then find another way because the preprocessor wasn\'t meant to do that.</p>\n</blockquote>\n\n<p>Interesting. I don\'t really consider a preprocessor to necessarily work this way. In the example provided, I am doing a simple text substitution, which is in-line with the definition of a preprocessor on <a href="http://en.wikipedia.org/wiki/Preprocessor" rel="nofollow noreferrer">Wikipedia</a>.</p>\n\n<p>If this isn\'t the proper use of a preprocessor, what should we call a simple text replacement, which generally needs to occur before a compilation?</p>\n'}, {'answer_id': 37893, 'author': 'Renaud Bompuis', 'author_id': 3811, 'author_profile': 'https://Stackoverflow.com/users/3811', 'pm_score': 2, 'selected': False, 'text': '<p>The main argument agaisnt building a pre-rocessor for C# is integration in Visual Studio: it would take a lot of efforts (if at all possible) to get intellisense and the new background compiling to work seamlessly.</p>\n\n<p>Alternatives are to use a Visual Studio productivity plugin like <a href="http://www.jetbrains.com/resharper/" rel="nofollow noreferrer">ReSharper</a> or <a href="http://devexpress.com/Products/Visual_Studio_Add-in/Coding_Assistance/" rel="nofollow noreferrer">CodeRush</a>.\nThe latter has -to the best of my knowledge- an unmatched templating system and comes with an excellent <a href="http://devexpress.com/Products/Visual_Studio_Add-in/Refactoring/" rel="nofollow noreferrer">refactoring</a> tool.</p>\n\n<p>Another thing that could be helpful in solving the exact types of problems you are referring to is an AOP framework like <a href="http://www.postsharp.net/" rel="nofollow noreferrer">PostSharp</a>.<br>\nYou can then use custom attributes to add common functionality.</p>\n'}, {'answer_id': 37941, 'author': 'Timbo', 'author_id': 1810, 'author_profile': 'https://Stackoverflow.com/users/1810', 'pm_score': 1, 'selected': False, 'text': '<p>To get the name of the currently executed method, you can look at the stack trace:</p>\n\n<pre><code>public static string GetNameOfCurrentMethod()\n{\n    // Skip 1 frame (this method call)\n    var trace = new System.Diagnostics.StackTrace( 1 );\n    var frame = trace.GetFrame( 0 );\n    return frame.GetMethod().Name;\n}\n</code></pre>\n\n<p>When you are in a property set method, the name is set_Property.</p>\n\n<p>Using the same technique, you can also query the source file and line/column info.</p>\n\n<p>However, I did not benchmark this, creating the stacktrace object once for every property set might be a too time consuming operation.</p>\n'}, {'answer_id': 1338420, 'author': 'Brett Ryan', 'author_id': 140037, 'author_profile': 'https://Stackoverflow.com/users/140037', 'pm_score': 1, 'selected': False, 'text': "<p>I think you're possibly missing one important part of the problem when implementing the INotifyPropertyChanged. Your consumer needs a way of determining the property name. For this reason you should have your property names defined as constants or static readonly strings, this way the consumer does not have to `guess' the property names. If you used a preprocessor, how would the consumer know what the string name of the property is?</p>\n\n<pre><code>public static string MyPropertyPropertyName\npublic string MyProperty {\n    get { return _myProperty; }\n    set {\n        if (!String.Equals(value, _myProperty)) {\n            _myProperty = value;\n            NotifyPropertyChanged(MyPropertyPropertyName);\n        }\n    }\n}\n\n// in the consumer.\nprivate void MyPropertyChangedHandler(object sender,\n                                      PropertyChangedEventArgs args) {\n    switch (e.PropertyName) {\n        case MyClass.MyPropertyPropertyName:\n            // Handle property change.\n            break;\n    }\n}\n</code></pre>\n"}, {'answer_id': 3228843, 'author': 'Norman H', 'author_id': 77329, 'author_profile': 'https://Stackoverflow.com/users/77329', 'pm_score': -1, 'selected': False, 'text': '<p>If you are ready to ditch C# you might want to check out the <a href="http://boo.codehaus.org/" rel="nofollow noreferrer">Boo</a> language which has incredibly flexible <a href="http://boo.codehaus.org/Part+17+-+Macros" rel="nofollow noreferrer">macro</a> support through <a href="http://en.wikipedia.org/wiki/Abstract_syntax_tree" rel="nofollow noreferrer">AST</a> (Abstract Syntax Tree) manipulations.  It really is great stuff if you can ditch the C# language.</p>\n\n<p>For more information on Boo see these related questions:</p>\n\n<ul>\n<li><a href="https://stackoverflow.com/questions/116654/best-non-c-language-for-generative-programming">Non-C++ languages for generative programming?</a></li>\n<li><a href="https://stackoverflow.com/questions/595593/who-is-using-boo-programming-language">https://stackoverflow.com/questions/595593/who-is-using-boo-programming-language</a></li>\n<li><a href="https://stackoverflow.com/questions/193862/boo-vs-ironpython">Boo vs. IronPython</a></li>\n<li><a href="https://stackoverflow.com/questions/172793/good-dynamic-programing-language-for-net-recommendation">Good dynamic programming language for .net recommendation</a></li>\n<li><a href="https://stackoverflow.com/questions/206539/what-can-boo-do-for-you">What can Boo do for you?</a></li>\n</ul>\n'}, {'answer_id': 19001173, 'author': 'Marcus Hansson', 'author_id': 512929, 'author_profile': 'https://Stackoverflow.com/users/512929', 'pm_score': 0, 'selected': False, 'text': '<p>At least for the provided scenario, there\'s a cleaner, type-safe solution than building a pre-processor:</p>\n\n<p>Use generics. Like so:</p>\n\n<pre><code>public static class ObjectExtensions \n{\n    public static string PropertyName&lt;TModel, TProperty&gt;( this TModel @this, Expression&lt;Func&lt;TModel, TProperty&gt;&gt; expr )\n    {\n        Type source = typeof(TModel);\n        MemberExpression member = expr.Body as MemberExpression;\n\n        if (member == null)\n            throw new ArgumentException(String.Format(\n                "Expression \'{0}\' refers to a method, not a property",\n                expr.ToString( )));\n\n        PropertyInfo property = member.Member as PropertyInfo;\n\n        if (property == null)\n            throw new ArgumentException(String.Format(\n                "Expression \'{0}\' refers to a field, not a property",\n                expr.ToString( )));\n\n        if (source != property.ReflectedType ||\n            !source.IsSubclassOf(property.ReflectedType) ||\n            !property.ReflectedType.IsAssignableFrom(source))\n            throw new ArgumentException(String.Format(\n                "Expression \'{0}\' refers to a property that is not a member of type \'{1}\'.",\n                expr.ToString( ),\n                source));\n\n        return property.Name;\n    }\n}\n</code></pre>\n\n<p>This can easily be extended to return a <code>PropertyInfo</code> instead, allowing you to get way more stuff than just the name of the property.</p>\n\n<p>Since it\'s an <code>Extension method</code>, you can use this method on virtually every object.</p>\n\n<p><br/><strong>Also, this is type-safe.</strong>\n<br/>Can\'t stress that enough.</p>\n\n<p>(I know its an old question, but I found it lacking a practical solution.)</p>\n'}, {'answer_id': 19099390, 'author': 'user2831877', 'author_id': 2831877, 'author_profile': 'https://Stackoverflow.com/users/2831877', 'pm_score': 2, 'selected': False, 'text': "<p>Using a C++-style preprocessor, the OP's code could be reduced to this one line:</p>\n\n<pre><code> OBSERVABLE_PROPERTY(string, MyProperty)\n</code></pre>\n\n<p>OBSERVABLE_PROPERTY would look more or less like this:</p>\n\n<pre><code>#define OBSERVABLE_PROPERTY(propType, propName) \\\nprivate propType _##propName; \\\npublic propType propName \\\n{ \\\n  get { return _##propName; } \\\n  set \\\n  { \\\n    if (value != _##propName) \\\n    { \\\n      _##propName = value; \\\n      NotifyPropertyChanged(#propName); \\\n    } \\\n  } \\\n}\n</code></pre>\n\n<p>If you have 100 properties to deal with, that's ~1,200 lines of code vs. ~100.  Which is easier to read and understand?  Which is easier to write?</p>\n\n<p>With C#, assuming you cut-and-paste to create each property, that's 8 pastes per property, 800 total.  With the macro, no pasting at all.  Which is more likely to contain coding errors?  Which is easier to change if you have to add e.g. an IsDirty flag?</p>\n\n<p>Macros are not as helpful when there are likely to be custom variations in a significant number of cases.</p>\n\n<p>Like any tool, macros can be abused, and may even be dangerous in the wrong hands.  For some programmers, this is a religious issue, and the merits of one approach over another are irrelevant; if that's you, you should avoid macros.  For those of us who regularly, skillfully, and safely use extremely sharp tools, macros can offer not only an immediate productivity gain while coding, but downstream as well during debugging and maintenance.</p>\n"}, {'answer_id': 67684070, 'author': 'Wolfgang Grinfeld', 'author_id': 6522669, 'author_profile': 'https://Stackoverflow.com/users/6522669', 'pm_score': 0, 'selected': False, 'text': '<p>Under VS2019, you do get enhanced ability to precompile, without losing intellisense, when using a generator (see <a href="https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/" rel="nofollow noreferrer">https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/</a>).</p>\n<p>For example: if you would be in need to remove readonly keywords (useful when manipulating constructors), then your generator could act as a precompiler to remove these keywords at compile time and generate the actual source that is to be compiled instead.</p>\n<p>Your original source would then look like the following (the §RegexReplace macro is to be executed by the Generator and subsequently commented out in the generated source):</p>\n<pre><code>#if Precompiled || DEBUG\n #if Precompiled\n    §RegexReplace(&quot;((private|internal|public|protected)( static)?) readonly&quot;,&quot;$1&quot;)\n #endif\n #if !Precompiled &amp;&amp; DEBUG\n namespace NotPrecompiled\n {\n #endif\n\n ... // your code\n\n #if !Precompiled &amp;&amp; DEBUG\n }\n #endif\n#endif // Precompiled || DEBUG\n</code></pre>\n<p>The generated source would then have:</p>\n<pre><code>#define Precompiled\n</code></pre>\n<p>at the top and the Generator would have executed the other required changes to the source.</p>\n<p>During development, you could thus still have intellisense, but the release version would only have the generated code. Care should be taken to never reference the NotPrecompiled namespace anywhere.</p>\n'}, {'answer_id': 67684319, 'author': 'Lasse V. Karlsen', 'author_id': 267, 'author_profile': 'https://Stackoverflow.com/users/267', 'pm_score': 0, 'selected': False, 'text': '<p>While there are plenty of good reflection-based answers here, the most obvious answer is missing and that is to use the compiler, at compile time.\nNote that the following method has been supported in C# and .NET since .NET 4.5 and C# 5.</p>\n<p>The compiler does in fact have some support for obtaining this information, just in a slightly roundabout way, and that is through the <a href="https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callermembernameattribute?view=net-5.0" rel="nofollow noreferrer">CallerMemberNameAttribute</a> attribute. This allows you to get the compiler to inject the name of the member that is <em>calling</em> a method. There are two sibling attributes as well, but I think an example is easier to understand:</p>\n<p>Given this simple class:</p>\n<pre><code>public static class Code\n{\n    [MethodImplAttribute(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]\n    public static string MemberName([CallerMemberName] string name = null) =&gt; name;\n    \n    [MethodImplAttribute(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]\n    public static string FilePath([CallerFilePathAttribute] string filePath = null) =&gt; filePath;\n    \n    [MethodImplAttribute(MethodImplOptions.AggressiveInlining | MethodImplOptions.AggressiveOptimization)]\n    public static int LineNumber([CallerLineNumberAttribute] int lineNumber = 0) =&gt; lineNumber;\n}\n</code></pre>\n<p>of which in the context of this question you actually only need the first method, you can use it like this:</p>\n<pre><code>public class Test : INotifyPropertyChanged\n{\n    private string _myProperty;\n    public string MyProperty\n    {\n        get =&gt; _myProperty;\n        set\n        {\n            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(Code.MemberName()));\n            _myProperty = value;\n        }\n    }\n    \n    public event PropertyChangedEventHandler PropertyChanged;\n}\n</code></pre>\n<p>Now, since this method is only returning the argument back to the caller, chances are that it will be inlined completely which means the actual code at runtime will just grab the string that contains the name of the property.</p>\n<p>Example usage:</p>\n<pre><code>void Main()\n{\n    var t = new Test();\n    t.PropertyChanged += (s, e) =&gt; Console.WriteLine(e.PropertyName);\n    \n    t.MyProperty = &quot;Test&quot;;\n}\n</code></pre>\n<p>output:</p>\n<pre><code>MyProperty\n</code></pre>\n<p>The property code actually looks like this when decompiled:</p>\n<pre><code>IL_0000 ldarg.0 \nIL_0001 ldfld   Test.PropertyChanged\nIL_0006 dup \nIL_0007 brtrue.s    IL_000C\nIL_0009 pop \nIL_000A br.s    IL_0021\nIL_000C ldarg.0 \n\n// important bit here\nIL_000D ldstr   &quot;MyProperty&quot;\nIL_0012 call    Code.MemberName\u2009(String)\n// important bit here\n\nIL_0017 newobj  PropertyChangedEventArgs..ctor\nIL_001C callvirt    PropertyChangedEventHandler.Invoke\u2009(Object, PropertyChangedEventArgs)\nIL_0021 ldarg.0 \nIL_0022 ldarg.1 \nIL_0023 stfld   Test._myProperty\nIL_0028 ret\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/37248', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/708/']