Skip to main content

How to Resolve Error "CS0685: Conditional member 'member' cannot have an out parameter" in C#

The Compiler Error CS0685 is a logical safety error involving the [Conditional] attribute. The message reads: "Conditional member 'MethodName' cannot have an out parameter".

In C#, the [Conditional("SYMBOL")] attribute tells the compiler: "If SYMBOL is not defined, delete every call to this method from the compiled code."

However, an out parameter imposes a strict contract: the method must assign a value to that parameter before returning. If the compiler removes the method call because the symbol isn't defined, the assignment never happens. This leaves the variable uninitialized, violating C#'s definite assignment rules. Therefore, C# forbids declaring a Conditional method with out parameters.

This guide explains the conflict and provides safer alternatives.

Understanding the Conflict​

To understand why this is an error, consider what happens when the conditional symbol is missing.

  1. The Code: bool success; TryLog(out success);
  2. The Contract: C# relies on TryLog to set success to true or false.
  3. The Attribute: [Conditional("DEBUG")] removes the line TryLog(out success); from the binary if "DEBUG" is missing.
  4. The Result: The variable success is declared but never assigned a value. Any subsequent code using success would crash or behave unpredictably.

Because the compiler cannot guarantee the method will run, it cannot guarantee the out variable will be assigned.

Scenario: The Invalid Definition​

This error usually occurs when developers try to create a debug-only method that returns status information via an out parameter.

Example of error:

using System.Diagnostics;

public class DebuggerHelper
{
// ⛔️ Error CS0685: Conditional member 'GetStatus' cannot have an out parameter.
// If "DEBUG" is not defined, this method call is stripped.
// The caller would be left with an unassigned 'status' variable.
[Conditional("DEBUG")]
public static void GetStatus(out string status)
{
status = "System is running...";
}
}

public class Program
{
static void Main()
{
string currentStatus; // Uninitialized

// If DEBUG is missing, this line vanishes.
// 'currentStatus' remains uninitialized.
DebuggerHelper.GetStatus(out currentStatus);

// Compiler error: Use of unassigned local variable 'currentStatus'
System.Console.WriteLine(currentStatus);
}
}

Solution 1: Use ref Instead of out​

Unlike out, a ref parameter must be initialized before being passed to the method. This satisfies the safety requirement: even if the method call is removed by the compiler, the variable still holds its initial value.

Solution: change the parameter to ref and initialize the variable at the call site.

using System.Diagnostics;

public class DebuggerHelper
{
// ✅ Correct: 'ref' allows the method to be conditional.
// If the method is removed, 'status' keeps its original value.
[Conditional("DEBUG")]
public static void GetStatus(ref string status)
{
status = "System is running...";
}
}

public class Program
{
static void Main()
{
// 1. Initialize the variable first
string currentStatus = "Unknown";

// 2. Pass by ref
DebuggerHelper.GetStatus(ref currentStatus);

// This works regardless of whether DEBUG is defined.
System.Console.WriteLine(currentStatus);
}
}

Solution 2: Use Preprocessor Directives (#if)​

If you specifically need out semantics (you don't want to initialize a dummy value beforehand), you cannot use the [Conditional] attribute. Instead, you must wrap both the definition and the call in #if blocks.

This ensures that if the method disappears, the code calling it (and the variable usage) disappears too, maintaining logic consistency.

Solution:

public class DebuggerHelper
{
// ✅ Correct: No attribute. We control compilation manually.
#if DEBUG
public static void GetStatus(out string status)
{
status = "System is running...";
}
#endif
}

public class Program
{
static void Main()
{
#if DEBUG
// This entire block exists only in Debug mode
string currentStatus;
DebuggerHelper.GetStatus(out currentStatus);
System.Console.WriteLine(currentStatus);
#endif
}
}
note

While Solution 1 (ref) is cleaner to read, Solution 2 (#if) allows you to completely strip the variable declaration itself from the Release build, which might be slightly more memory efficient.

Conclusion​

CS0685 ensures variable assignment safety.

  1. Understand the Constraint: If a method might vanish (due to [Conditional]), it cannot be responsible for initializing variables (out).
  2. Use ref: This is the standard fix. Initialize the variable yourself before passing it.
  3. Use #if: If you must use out, wrap the logic in preprocessor directives instead of using attributes.