Skip to main content

How to Resolve Error "CS0663: Cannot define overloaded methods that differ only on ref and out" in C#

The Compiler Error CS0663 is a Method Overloading restriction error. The message reads: "Cannot define overloaded methods that differ only on ref and out".

In C#, ref and out keywords provide different rules for initialization and assignment at the language level (e.g., out must be assigned before returning). However, at the Common Language Runtime (CLR) level (in the compiled IL code), they are treated identically—both are simply references (pointers) to a variable.

Because the compiled code for a method taking ref int looks identical to a method taking out int, the runtime cannot distinguish between them. Therefore, you cannot overload a method based solely on this distinction.

Understanding the CLR Representation

  • C# View:
    • void Method(ref int x) $\rightarrow$ "Read/Write access. x is initialized."
    • void Method(out int x) $\rightarrow$ "Write-only access initially. x must be assigned."
  • CLR (IL) View:
    • void Method(int& x)
    • void Method(int& x)

Since the resulting signatures in the binary are identical, the compiler blocks this definition to prevent runtime collisions.

note

You can overload based on ref/out vs. value.

  • void Method(int x)
  • void Method(ref int x) This is valid because one takes a value and the other takes a reference.

Scenario: The Ambiguous Overload

This error occurs when you try to create two versions of a method to handle slightly different data flow requirements using the same parameter types.

Example of error:

public class DataHandler
{
// Method 1: Takes an input/output parameter
public void Process(ref int value)
{
value++;
}

// ⛔️ Error CS0663: Cannot define overloaded methods that differ only on ref and out.
// The compiler sees this signature as identical to the one above.
public void Process(out int value)
{
value = 10;
}
}

Solution: Rename or Change Parameters

Since you cannot rely on overloading here, you must make the signatures distinct in another way.

Option A: Rename the Methods

Give them names that reflect their behavior (Input/Output vs Output Only).

public class DataHandler
{
// ✅ Correct: Distinct names
public void UpdateValue(ref int value)
{
value++;
}

public void GetNewValue(out int value)
{
value = 10;
}
}

Option B: Use Different Parameter Types

If the logic dictates it, maybe the types should differ.

public class DataHandler
{
public void Process(ref int value) { }

// ✅ Correct: Different parameter type (long vs int) creates a valid overload.
public void Process(out long value)
{
value = 10;
}
}

Conclusion

CS0663 is a limitation of the underlying .NET runtime.

  1. Check Signatures: Do you have Method(ref T) and Method(out T)?
  2. Understand IL: Remember that ref and out compile to the same thing (ByRef).
  3. Fix: Rename one of the methods or change the parameter list to make them unique.