How to Resolve Warning "CS0419: Ambiguous reference in cref attribute" in C#
The Compiler Warning CS0419 is a documentation comment warning. The message reads: "Ambiguous reference in cref attribute: 'Method'. Assuming 'Method(int)', but could have also matched other overloads including 'Method(string)'."
In C#, XML documentation comments (triple slash ///) allow you to create hyperlinks to other parts of your code using the <see cref="..."/> tag. If you link to a method by name (e.g., cref="MyMethod"), but that method has multiple overloads (e.g., one taking an int and one taking a string), the compiler does not know which one you meant to link to. It picks one arbitrarily and issues this warning to tell you the link might be incorrect.
This guide explains how to disambiguate these references in your documentation.
Understanding cref Ambiguity
The cref attribute stands for Code Reference. When the compiler processes your comments to generate an XML documentation file, it needs to generate a unique ID for every link.
- Unique Name: If you link to a class
MyClassor a unique methodRun(), the name alone is enough. - Ambiguous Name: If you link to
Calculateand you haveCalculate(int)andCalculate(double), the name "Calculate" maps to two different unique IDs.
To resolve this, you must be specific about the signature (parameters) of the target member.
Scenario: Overloaded Methods
This is the most common cause. You refer to a method by its simple name, ignoring the fact that multiple versions exist.
Example of warning:
public class Calculator
{
/// <summary>
/// Performs a calculation.
/// See also <see cref="Add"/> for details.
/// </summary>
public void DoMath() { }
// ⛔️ Warning CS0419: Ambiguous reference in cref attribute: 'Add'.
public int Add(int a, int b) => a + b;
public double Add(double a, double b) => a + b;
}
Solution 1: Specify Parameter Types
To fix the ambiguity, you must include the parameter types inside parentheses () in the cref attribute. You do not need to include the parameter names, only their types.
Example of warning:
public class Calculator
{
/// <summary>
/// Performs a calculation.
/// See <see cref="Add(int, int)"/> for integer math,
/// or <see cref="Add(double, double)"/> for floating point.
/// </summary>
public void DoMath() { }
// ✅ Correct: The documentation links are now specific.
public int Add(int a, int b) => a + b;
public double Add(double a, double b) => a + b;
}
Arrays and Pointers:
If the parameter is an array, use square brackets: cref="Process(int[])".
If it uses ref or out or pointers, you generally do not need to specify those modifiers in cref unless they are the only difference between overloads (which is rare).
Solution 2: Handling Generics
When linking to generic methods or types, the syntax requires explicit handling of the type parameters. In XML documentation, using angle brackets <T> can confuse the XML parser. While modern Visual Studio handles <T> okay, the standard convention is often to use curly braces {T} or escape characters.
Example of warning
public class Container
{
public void Add(int i) { }
public void Add<T>(T item) { }
/// <summary>
/// Uses <see cref="Add"/> to store data.
/// </summary>
public void Process() { }
// ⛔️ Warning CS0419: Ambiguous between 'Add(int)' and 'Add<T>(T)'
}
Solution
Specify the generic parameters.
public class Container
{
public void Add(int i) { }
public void Add<T>(T item) { }
/// <summary>
/// Uses <see cref="Add{T}(T)"/> to store generic data.
/// </summary>
public void Process() { }
// ✅ Correct: {T} denotes the generic type parameter.
}
Solution 3: Operators and Casts
If you define implicit or explicit conversion operators, linking to them requires specific syntax using the op_ naming convention or the operator keyword depending on the tool version, but standard C# cref supports the operator keyword.
Example of warning
public class Currency
{
// ⛔️ Warning CS0419: Assuming 'implicit operator int',
// but could match 'implicit operator float'.
/// <see cref="operator implicit"/>
public void Convert() { }
public static implicit operator int(Currency c) => 0;
public static implicit operator float(Currency c) => 0.0f;
}
Solution
Specify the target type of the conversion.
public class Currency
{
// ✅ Correct: Specify the destination type
/// <see cref="implicit operator int(Currency)"/>
public void Convert() { }
public static implicit operator int(Currency c) => 0;
public static implicit operator float(Currency c) => 0.0f;
}
Conclusion
CS0419 helps ensure your documentation links actually go where you intend them to.
- Simple Overloads: Add parentheses with types:
cref="Method(int, string)". - No Arguments: If the method takes no arguments, use empty parentheses:
cref="Method()". - Generics: Use curly braces for generic types:
cref="Method{T}(T)".