The OO crowd sometimes just goes overboard. C# and #defines are an example. C# does provide support for defines, but not for defines with values. So you can write code like:
#if foo Console.WriteLine("foo is defined"); #else Console.WriteLine("shoot, its not defined"); #endif
But, the designers left out support for #define FOO=VALUE on the grounds that its “macros are a bad idea in general”. See other non-thinkers that spout the same idea here.
The reason these guys think its okay to not have macros is because they’ve never coded in the large. They’ve never built real projects. For any developer that HAS actually written real code, they know that real code invariably requires a set of tools and resources to fully assemble the final product. This includes utility libraries, installers, uninstallers, profilers, memory checking tools, etc, etc. And you always want to have a few key things that you pass between each of these tools. One of the simplest ways to do this is to use the #define NAME=VALUE syntax. Its not graceful, but its so simple that almost every tool out there provides support for it. When you are using someone else’s tool, you just don’t have the luxury to be screwing around with ideals of “macros are bad”.
Ack. Well, if you haven’t guessed it already, today I’m trying to automate my build processes. I have different tools to link together, and the WEAK LINK in the chain is the C# compiler lacking macros.
Solution
The solution I’ve settled on so far is use of environment variables. Its not too bad, and mostly usable in other programs as well. Code looks about like this:
string version = System.Environment.GetEnvironmentVariable("PROG_VERSION");
But this is a lot more cumbersome that using pre-processor macros because its inline code. Now you’ve got to make sure this is initialized and loaded in the right place, etc etc. I’ll keep looking.
Ack. Get off your high-horse and allow macros!!!!!
Well, the Environment variables haven’t worked out too well for me either. I really want a COMPILE TIME directive! Ah well.
Another interesting topic, yet somewhat unrelated is the notion of “Friend”, another missing construct from C#.
I’m writing a unit test to test my classes. I need my test to be separate from my code so that it isn’t included in the ultimate shipping product. In the test, I need to access private members so that I can conjure up test instances of the class and do other nasty things that you’d only do while testing. But I can’t. Why not? Because I can’t have a “friend” class like you can in C++. I’m sure this is another case where the OO guys said, “friend classes are an abomination – get rid of them!!”. Its not that I disagree; I would certainly avoid friend status in production code. But I still need to write a test case, and friend is the right answer.
The problem is that the real world needs some of these things. The OO compiler guys want to forbid any use of the “bad stuff” because they think it helps people write better code. Well, here I am now, changing methods from private to public just so that I can write a test code. Who made the code better? Even though we developers know we shouldn’t use things like “friend” often, there are some very legitimate cases where we should be allowed to do so.
An interesting article on this can be found here at this link.
I shouldn’t always be ranting. I actually like C#.