Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Queston on avoiding the preprocessor

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Queston on avoiding the preprocessor

    To be clear where I am coming from:
    • I understand that using preprocessor directives is actively discouraged, with the sole exception of #region.
    • I very much prefer to stay within supported guidelines.
    • This post is to ask about best practices with the system the way it is (and not about arguing that the system should support the preprocessor)
    I know of one problem that can occur when using #if -- if you enclose any property with the [NinjaScriptProperty] attribute inside #if ... #endif then the code NT adds at the end will still reference it and the compilation will fail. That's fixable by commenting out such lines. The code will then compile.

    My source has a fair bit of trace/debugging code, including a sizable presence in my GUI when compiled with debugging turned on. I don't want either the code or, especially, the GUI impact for non-debug builds. It seems to me that there are two separate questions: how to avoid the unwanted code and how to avoid the unwanted properties. I'd like to know what the supported best practices are for each.

    Code -- can be excluded several ways. My understanding is that only the first of these is supported. (Am I correct that the [Conditional] attribute is not supported?)
    • I believe the recommended way is to not get rid of the code, but to have a runtime check that avoids executing it. That is, in principle, doable. One could define a single const , which would not be a lot more work than depending on the compiler defining DEBUG.
    • Where possible, I would prefer to use the [Conditional] attribute, which works for void methods. That stops all calls in a non-debug build, it seems cleaner and is very visible in the source. (Is this supported? I would guess not.)
    • #if ... #endif would be needed where [Conditional] is not applicable -- any method returning a value. This is clearly not supported.
    Properties -- the properties that control my debug/trace capabilities are a significant presence in my GUI when they are enabled (debug builds). They really must not be there for non-debug builds.
    • None of these properties has the [NinjaScriptProperty] attribute so, as far as I know, the automatic code generation ignores them.
    • I do not know how to eliminate them from a build without using #if ... #endif.
    • What is the supported/recommended method of excluding such properties from a non-debug build?
    For what it is worth, there is one other time I use #if -- when porting code.
    • Use it to exclude code that I am having trouble compiling so I can get on with my work. I'll get back to that troublesome part later.
      • This is a compile-time issue, not a runtime issue, so the recommended use of a runtime check is not relevant.
      • Is there a supported way to deal with this?
    • Use it to avoid deleting some code being ported from the source until I am certain that the new code I am replacing it with does the job.
      • This may be just a few lines within a method rather than an entire method.
      • This could be handled with a runtime check. That could work, unlike a couple of the other issues I have raised.
    =====
    I guess the two biggest needs that I don't see a supported way to handle are excluding properties that affect the GUI and segregating code that will not yet compile. What are the best practices for these issues?

    Thanks for your consideration.
    Last edited by ETFVoyageur; 05-14-2024, 08:25 PM.

    #2
    Hello ETFVoyageur,

    "I understand that using preprocessor directives is actively discouraged, with the sole exception of #region."

    Not just discouraged, this is completely unsupported and will break NinjaTrader's ability to compile, export, and use the script.

    "My source has a fair bit of trace/debugging code, including a sizable presence in my GUI when compiled with debugging turned on. I don't want either the code or, especially, the GUI impact for non-debug builds."

    In the logic you can use conditions to control if information is printed or written to separate text file for logging. For any variable or method declarations, these will not be optional. You could choose to have two versions of the script, one for production with all of the unneeded variable declarations (and logic if you wanted) removed from the script, and one for debugging with the extra code added.

    "Code -- can be excluded several ways. My understanding is that only the first of these is supported. (Am I correct that the [Conditional] attribute is not supported?)"

    The [Conditional] attribute is not officially documented or supported for use with NinjaScript.

    "I believe the recommended way is to not get rid of the code, but to have a runtime check that avoids executing it."

    For run-time logic in a method, you can use a bool that is checked in a condition that turns off the debugging logic.
    However, for a production script, it would recommended to remove the debugging code.

    Where possible, I would prefer to use the [Conditional] attribute, which works for void methods. That stops all calls in a non-debug build, it seems cleaner and is very visible in the source. (Is this supported? I would guess not.)

    This would not be officially supported or documented for use in NinjaScript.
    There can be limitations using unsupported code and advanced C# concepts in a NinjaScript, so your mileage may vary

    "#if ... #endif would be needed where [Conditional] is not applicable -- any method returning a value. This is clearly not supported."

    No, this is not supported.

    "Properties -- the properties that control my debug/trace capabilities are a significant presence in my GUI when they are enabled (debug builds). They really must not be there for non-debug builds."

    It would be necessary to remove these if you don't want them present.
    It is possible to hide properties with a custom type converter, but this does not work in the Strategy Analyzer.


    "None of these properties has the [NinjaScriptProperty] attribute so, as far as I know, the automatic code generation ignores them."

    The NinjaTrader generated code and internal compilation process is affected by all public variables, including those that are commented out in multi-line comment blocks /* */. Using the Browsable(false) attribute can prevent these from being included in the overloads.

    "I do not know how to eliminate them from a build without using #if ... #endif.
    What is the supported/recommended method of excluding such properties from a non-debug build?"

    Comment out or delete the code from the production version of the script.

    "Use it to exclude code that I am having trouble compiling so I can get on with my work. I'll get back to that troublesome part later.
    This is a compile-time issue, not a runtime issue, so the recommended use of a runtime check is not relevant.
    Is there a supported way to deal with this?"

    There is not a supported way to exclude declarations other than commenting this out or removing it. You can use a condition that checks a bool to avoid processing logic within a method.

    "Use it to avoid deleting some code being ported from the source until I am certain that the new code I am replacing it with does the job.
    This may be just a few lines within a method rather than an entire method.
    This could be handled with a runtime check. That could work, unlike a couple of the other issues I have raised."

    You can comment the code out.​​
    Chelsea B.NinjaTrader Customer Service

    Comment


      #3
      I'll just have to see how that all evolves. I cannot imagine any responsible development process that relies on two separate physical versions of their code. That would be dangerous -- a problem just waiting to happen.

      I can see one runtime way to deal with the properties. Declare a const variable that will be set to indicate either debug or release. Define a custom attribute such as [DebugOnly]. Then override ModifyProperties to remove any property tagged with that attribute when the const variable indicates it is a release build.

      One thing you said surprised me -- that the advice to comment things out does not work with /* */ commenting out multiple lines. Does that mean that the advice to comment requires entirely single-line comments? I did not previously understand that, but I would infer so from your remark. Is it the case that either style of single-line comments is OK (// or /* ... */)?

      Comment


        #4
        Hello ETFVoyageur,

        NinjaTrader uses reflection and regular expressions to parse a file as text line by line and make sure any referenced classes or enums are available. With both, neither the reflection or the regex are able to see multi-line comment marks such as /* */ that are on different lines. They are only able to ignore lines which start with single line comment marks.

        Using block comments or multi-line comments /* */ on a variable, method, or class declaration will cause the regex to read the text there, and interpret is as that there should be this public property or a method that the reflection is unable to see.

        In general, comment out code with single line comment marks // instead of using multi-line or block comments /* */.
        Chelsea B.NinjaTrader Customer Service

        Comment


          #5
          Thanks for the info ... I had not realized that. No /* ... */ even if on a single line. Got it now -- the only supported way to exclude something from compiling is //-style single-line comments. Thanks for explaining that -- I had not realized the requirement was quite that severe.

          Comment

          Latest Posts

          Collapse

          Topics Statistics Last Post
          Started by Geovanny Suaza, 02-11-2026, 06:32 PM
          0 responses
          596 views
          0 likes
          Last Post Geovanny Suaza  
          Started by Geovanny Suaza, 02-11-2026, 05:51 PM
          0 responses
          343 views
          1 like
          Last Post Geovanny Suaza  
          Started by Mindset, 02-09-2026, 11:44 AM
          0 responses
          103 views
          0 likes
          Last Post Mindset
          by Mindset
           
          Started by Geovanny Suaza, 02-02-2026, 12:30 PM
          0 responses
          556 views
          1 like
          Last Post Geovanny Suaza  
          Started by RFrosty, 01-28-2026, 06:49 PM
          0 responses
          554 views
          1 like
          Last Post RFrosty
          by RFrosty
           
          Working...
          X