> ## Documentation Index
> Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt
> Use this file to discover all available pages before exploring further.

# C# Conditional Attribute

The `[Conditional]` attribute (`System.Diagnostics.ConditionalAttribute`) is an attribute that instructs the C# compiler to conditionally omit method invocations or attribute emissions based on the definition of a specified preprocessor symbol. When applied, the compiler evaluates the symbol; if the symbol is not defined, all calls to the target method—including the evaluation of its arguments—are stripped from the Intermediate Language (IL) during compilation. The method definition itself remains intact in the compiled assembly.

Crucially, the presence of the preprocessor symbol is evaluated based on the **caller's** compilation context (the project or file where the method is invoked), not the **callee's** compilation context (the project or file where the method is defined).

## Syntax and Invocation

To demonstrate the separation of contexts, the following example divides the method definition (callee) and the method invocation (caller).

```csharp theme={"dark"}
// --- Callee Context (e.g., Library.cs) 
using System.Diagnostics;

public class ConditionalExample
{
    // The method definition is always compiled into the assembly's IL.
    [Conditional("FEATURE_X")]
    public static void ExecuteFeature(int value)
    {
        // Method implementation
    }
}
```

```csharp theme={"dark"}
// --- Caller Context (e.g., Program.cs) 
#define FEATURE_X // Preprocessor symbol defined in the caller's context

public class Program
{
    public static void Main()
    {
        // Because FEATURE_X is defined in this context, the compiler emits this call.
        // If #define FEATURE_X is removed, the compiler strips this invocation entirely.
        ConditionalExample.ExecuteFeature(42); 
    }
}
```

## Compilation Mechanics

* **Caller Context Evaluation:** Because the symbol is evaluated at the call site, a library can compile a `[Conditional]` method into its assembly permanently, while the decision to emit invocations is dictated entirely by the consuming application's build configuration. This is a primary distinction from `#if` / `#endif` directives, which physically exclude code based on the assembly's own compilation context.
* **Call-Site Omission:** The compiler removes the invocation at the call site but does not remove the method declaration from the defining assembly.
* **Argument Evaluation:** If the method call is omitted, any expressions passed as arguments to that method are not evaluated. This prevents unintended side effects from executing when the method call is stripped.
* **Logical OR Evaluation:** Applying multiple `[Conditional]` attributes to a single method results in a logical OR operation. If *any* of the specified symbols are defined in the caller's context, the method calls are included in the compilation.

```csharp theme={"dark"}
[Conditional("ALPHA")]
[Conditional("BETA")]
public void Execute() { } // Call is emitted if ALPHA OR BETA is defined by the caller
```

## Structural Constraints

The C# compiler enforces strict rules on where and how the `[Conditional]` attribute can be applied:

1. **Return Type:** The target method must have a `void` return type. Methods returning a value cannot be conditional because the compiler cannot guarantee a return value at the call site if the invocation is omitted.
2. **Parameter Restrictions:** The method cannot contain `out` parameters. If the method call is omitted, the `out` parameter would remain unassigned, violating C# definite assignment rules. `ref` parameters are permitted.
3. **Member Types:** It can only be applied to methods or attribute classes. It cannot be applied to properties, fields, events, or constructors.
4. **Abstract Methods:** The method cannot be marked as `abstract`.
5. **Entry Point:** The method cannot be the entry point of an application (e.g., `Main`).
6. **Interface Implementations:** It cannot be applied to an interface method declaration or to a method that implements an interface.
7. **Overrides:** If a `virtual` method is marked with `[Conditional]`, any overridden implementations in derived classes are implicitly conditional and cannot explicitly declare the `[Conditional]` attribute.
8. **Delegates:** You cannot create a delegate pointing to a conditional method, as the compiler cannot conditionally omit delegate invocations.

## Application to Attribute Classes

When applied to a custom attribute class, the `[Conditional]` attribute dictates whether the custom attribute is emitted into the metadata of the target assembly. The evaluation context remains the assembly where the attribute is applied.

```csharp theme={"dark"}
#define INCLUDE_METADATA // Must precede all other tokens in the file

using System;
using System.Diagnostics;

// --- Attribute Definition 
[Conditional("INCLUDE_METADATA")]
[AttributeUsage(AttributeTargets.Class)]
public class CustomTrackingAttribute : Attribute { }

// --- Attribute Application 
[CustomTracking] // Emitted into IL metadata only because INCLUDE_METADATA is defined
public class TargetClass { }
```

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor C# Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
