views:

1581

answers:

10
+9  Q: 

C# Preprocessor

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++.

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:

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);
    }
  }
}

Would it be a good idea to write a pre-processor to handle extremely simple cases like this? Steve McConnell wrote in Code Complete (p208):

Write your own preprocessor If a language doesn't include a preprocessor, it's fairly easy to write one...

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.

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

+3  A: 

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

You can always use the C pre-processor -- C# is close enough, syntax-wise. M4 is also an option.

John Millikin
+5  A: 

Consider taking a look at an aspect-oriented solution like PostSharp, 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).

Matt Hamilton
A: 

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.

I'm not sure there's much of a demand for that sort of thing though.

billpg
+2  A: 

I know a lot of people think short code equals elegant code but that isn't true.

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.

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 flexibility 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 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.

Jorge Córdoba
I couldnt agree more
Allen
A: 

@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.

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 Wikipedia.

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?

Brad Leach
And for that you should use a string constant, any reasons for not doing it? Also, what would be the type of your #property? What if I define #property as double? Why would I want to substitute a constant by a prepocessor directive?
Jorge Córdoba
Given my example in the question, having to maintain a constant that represents the name of the property will unfortunately not save any maintenance. Granted, if I needed to reuse the string in any other parts in the class, I would certainly use a constant.
Brad Leach
(cont) What might be interesting is having both the #Property syntax (defaults to current property), and #Property.MyProperty syntax - a tool refactorable construct, which would produce a compile time error if not mapped to an actual property and avoiding the runtime overhead of reflection.
Brad Leach
+3  A: 

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.

Alternatives are to use a Visual Studio productivity plugin like ReSharper or CodeRush. The latter has -to the best of my knowledge- an unmatched templating system and comes with an excellent refactoring tool.

Another thing that could be helpful in solving the exact types of problems you are referring to is an AOP framework like PostSharp.
You can then use custom attributes to add common functionality.

Renaud Bompuis
A: 

To get the name of the currently executed method, you can look at the stack trace:

public static string GetNameOfCurrentMethod()
{
    // Skip 1 frame (this method call)
    var trace = new System.Diagnostics.StackTrace( 1 );
    var frame = trace.GetFrame( 0 );
    return frame.GetMethod().Name;
}

When you are in a property set method, the name is set_Property.

Using the same technique, you can also query the source file and line/column info.

However, I did not benchmark this, creating the stacktrace object once for every property set might be a too time consuming operation.

Timbo
Beware of using System.Diagnostics.StackTrace(). I know I've read that it isn't a reliable source of information, especially once you travel up the call stack (probably read on "The Old New Thing"). The convention to call property setters set_Property is also an internal .Net thing and hence is subject to change.The most reliable way of safely referring to a property afaik is through a lambda expression. Otherwise use aspect oriented solutions as suggested here.
Andre Luus
A: 

I agree with you, I am in a pain right now.

I have a project in C# where my properties call a static method of class and the method initialize the variable, but now I need the name of the property because I will need to use reflection on it later, dinamycally. I have all my properties calling that method and I thought "well, it is very organized, when I need something, just change that static method." and the NICEST part of this, is that I can't find the property name from the static method, only using stacktrace which I am not going to use because of performance of course

now, i will have to edit ALL MY F*CKING PROPERTIES to add a string constant because SOMEONE finds preprocessor a bad thing. yeah, readbility MY A**, you are not going to read my code, why restringe my creativity based on your creativity? man, I am really pissed, lost 10 hours on this and nothing. I can't believe i will have to edit all properties.

is there any framework with reflection and stuff like c#, but with freedom to do what you want?

Jonathan
+1  A: 

Hi there Brad, 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?

public static string MyPropertyPropertyName
public string MyProperty {
    get { return _myProperty; }
    set {
        if (!String.Equals(value, _myProperty)) {
            _myProperty = value;
            NotifyPropertyChanged(MyPropertyPropertyName);
        }
    }
}

// in the consumer.
private void MyPropertyChangedHandler(object sender,
                                      PropertyChangedEventArgs args) {
    switch (e.PropertyName) {
        case MyClass.MyPropertyPropertyName:
            // Handle property change.
            break;
    }
}
Brett Ryan
A: 

If you are ready to ditch C# you might want to check out the [Boo][1] language which has incredibly flexible [macro][2] support through [AST][3] (Abstract Syntax Tree) manipulations. It really is great stuff if you can ditch the C# language. For more information on Boo see these related questions:

http://stackoverflow.com/questions/116654/best-non-c-language-for-generative-programming http://stackoverflow.com/questions/595593/who-is-using-boo-programming-language http://stackoverflow.com/questions/193862/boo-vs-ironpython http://stackoverflow.com/questions/172793/good-dynamic-programing-language-for-net-recommendation http://stackoverflow.com/questions/206539/what-can-boo-do-for-you

[1]: http://boo.codehaus.org/ Boo

[2]: http://boo.codehaus.org/Part+17+-+Macros macro

[3]: http://en.wikipedia.org/wiki/Abstract_syntax_tree AST

Norman H