7

In C, I could declare a compiler directive as follows:

#define MY_NUMBER 10

However, in C#, I only appear to be able to do this:

#define MY_NUMBER

Which is obviously useless in this case.

Is this correct, or am I doing something wrong? If not, can anyone suggest a way of doing this, either at namespace or solution level? I thought of maybe creating a static class, but that seems to be overkill for one value.

Paul Michaels
  • 16,185
  • 43
  • 146
  • 269

6 Answers6

6

Yes, it is correct.

Here's a quote from the MSDN documentation:

The pre-processing directives provide the ability to conditionally skip sections of source files, to report error and warning conditions, and to delineate distinct regions of source code. The term "pre-processing directives" is used only for consistency with the C and C++ programming languages. In C#, there is no separate pre-processing step; pre-processing directives are processed as part of the lexical analysis phase.

So you can't really define compiler constants, like in C and C++.

Related resources:

Enrico Campidoglio
  • 56,676
  • 12
  • 126
  • 154
5

A lot of the other answers suggest using a public const field. Note however that a public const will be compiled into assemblies referencing it, forcing you to recompile not only the assembly it is defined in but also every assembly referencing it if you ever change the value of the const.

If you are not certain the value will never have to change, a public static readonly field is a better alternative.

josef.axa
  • 1,163
  • 12
  • 15
  • Thanks; this is really helpful! I never knew that. – Robert Fraser Jun 11 '10 at 07:19
  • @RobertFraser Yes, enums are **never** meant to change, they are just integer constants with fancy compilator magic on top ([Source](http://www.dotnetperls.com/enum-performance)). More importantly such a breaking change has a low chance of getting caught at runtime and virtually zero chance of getting caught in compilation. Assemblies that use your enum / constant might still run but could start exhibiting random behavior. So NEVER change a public constant. There is no telling what kind of havoc this can wreck or how much damage is done before the problem is caught! If in doubt use readonly. – AnorZaken Feb 20 '19 at 18:49
  • @AnorZaken I can't help but feel that was a design mistake. It's not even an optimization, since the JIT can do constant folding just as well as the compiler. Oh well, hindsight's 20/20. – Robert Fraser Mar 01 '19 at 16:39
  • @RobertFraser Eric Lippert made a comment on here long ago where he called the enum implementation the biggest design mistake in C#. It wasn't because of it being a constant though, but rather because a) it's an ugly hack to mimic old enum from C++ (all enum code in the framework is horribly wonky and pollutes the entire type system), and b) because it serves two disparate purposes - named constants and flags - so it should have been split into two separate types (like in Java). Personally I don't think constants are a mistake, but perhaps the compiler should warn you when a const is public. – AnorZaken Mar 03 '19 at 15:37
3

Yes, you're correct. const and readonly are really your only options.

Matthew Flaschen
  • 278,309
  • 50
  • 514
  • 539
3

You can define a const or a static readonly, and if you want it conditionally you can wrap it in an #if directive

#if DEBUG
private const int MY_NUMBER = 10;
#else
private const int MY_NUMBER = 20;
#endif
Thomas
  • 7,933
  • 4
  • 37
  • 45
1

Use public const


AFAIK,

C# does not use pre-processor defines to perform replacement in code, so you have to use a constant.

This should do the trick:

public const int MY_NUMBER = 10;
Janusz
  • 187,060
  • 113
  • 301
  • 369
TheCodeArtist
  • 21,479
  • 4
  • 69
  • 130
1

You might also like to check enums, like

enum Numbers
{
    Nothing = 0,
    Dads = 5,
    My = 10,
    LittleJims = 25
}

So, instead of C's MY_NUMBER, you have Numbers.My.