0
#if DEBUG
    string s = @"
# text";
#endif

If DEBUG is defined the above code builds without error using Visual Studio 2017.

If DEBUG is not defined, the build fails with this error:

error CS1024: Preprocessor directive expected

The issue has been reported to the C# language design community here.

I can work around the problem by using non-verbatim strings:

#if DEBUG
    string s = "\n" +
"# text";
#endif

In my particular use case I would rather keep my strings verbatim. Is there a different - possibly better - way to work around this problem?

ZunTzu
  • 7,244
  • 3
  • 31
  • 39

2 Answers2

1

Obviously there is no way to avoid this problem as it is, unless maybe its your VS.

However if its giving yuo problems you could try using StringBuilder , it may give you a more consistent look

#if DEBUG

    Var sb = new StringBuilder();

    S.AppendLine("rah");
    S.AppendLine("");
    S.AppendLine("# Text");
    S.AppendLine("# Blah");

#endif
TheGeneral
  • 79,002
  • 9
  • 103
  • 141
  • Thanks. Spreading the string over several lines is indeed a good idea. I have edited my question to show an alternative solution using a concatenation of string literals, each ending with `\n" +`. However I don't think introducing StringBuilder has benefits over such a concatenation of string literals. – ZunTzu Feb 12 '18 at 09:38
1

If you can't go through, then go around.

const string shellScript = @"
# text";
#if DEBUG
    string s = shellScript;
#endif

The compiler will not warn about unused constants, nor (I hope) will any overzealous static analysers. As an added benefit (?) you get to explain what the verbatim string actually represents.

Jeroen Mostert
  • 27,176
  • 2
  • 52
  • 85
  • In my actual use case the scope of `#if DEBUG` is much larger: it encompasses both the method containing the string literal and the class containing the method. To make your idea work I would have to define a new class to contain the string variable, which means the string literal would end up very far from where it is used. I would rather not do that. But I am confident other readers will find this answer useful. – ZunTzu Feb 12 '18 at 09:49
  • 1
    @ZunTzu: in that case, another option is excluding the whole file through your project configuration with a condition (`Condition="'$(Configuration)'=='Debug'"`). Messing around with the project file is much less intuitive than preprocessor directives, of course. – Jeroen Mostert Feb 12 '18 at 10:07
  • It is not really relevant to my original question but it is very relevant to what I am trying to achieve. The whole point for me is to avoid shipping unit tests (yes, my unit tests are in the same project as my production code, I like it that way). I will try your idea! Thanks a lot! – ZunTzu Feb 12 '18 at 10:35
  • @ZunTzu: in *that* case, you can group all the unit test files in their own `` and apply the condition to that. Of course, a separate project is cleaner still, but you're already off the beaten path there. :-) – Jeroen Mostert Feb 12 '18 at 10:39