How to Resolve Warning "CS0473: Explicit interface implementation matches more than one interface member" in C#
The Compiler Warning CS0473 is a generic type resolution warning. The message reads: "Explicit interface implementation 'method name' matches more than one interface member. Which interface member is actually chosen is implementation-dependent. Consider using a non-explicit implementation instead."
This warning occurs in specific Generic scenarios where an interface defines two distinct methods, but when implemented with a specific type (e.g., int), those two methods end up having the exact same signature. If you try to implement them using Explicit Interface Implementation, the Common Language Runtime (CLR) cannot reliably determine which of the two interface slots your method is supposed to fill.
This guide explains how generic substitution causes this collision and how to resolve it safely using implicit implementation.
Understanding Generic Signature Collapse
Consider a generic interface defined like this:
public interface IGeneric<T>
{
void Process(T value); // Method A
void Process(int value); // Method B
}
- If
Tisstring, the signatures areProcess(string)andProcess(int). They are distinct. - If
Tisint, the signatures becomeProcess(int)andProcess(int). They are identical.
When the signatures collapse, the interface effectively requires two identical methods. If you use explicit implementation (void IGeneric<int>.Process(int value)), you are trying to attach code to a specific slot. However, since both slots look identical, the CLI (Common Language Infrastructure) specification does not guarantee which slot gets bound, leading to unpredictable behavior.
Scenario: The Colliding Explicit Implementation
This error occurs when you implement a generic interface with a specific type that causes an overload collision, and you attempt to hide that implementation using the explicit syntax.
Example of warning:
interface ITest<T>
{
// If T becomes int, this is Test(int)
void Test(T t);
// This is always Test(int)
void Test(int i);
}
// We implement the interface with T = int
public class Implementation : ITest<int>
{
// ⛔️ Warning CS0473: Explicit interface implementation matches more than
// one interface member.
// The compiler asks: "Is this filling the 'T' slot or the 'int' slot?"
// Since both slots look like 'void Test(int)', it's ambiguous.
void ITest<int>.Test(int arg)
{
System.Console.WriteLine("Processing int");
}
}
Although this is a warning in C#, the behavior at runtime is considered "implementation-dependent," meaning it could behave differently on different versions of .NET or different platforms (Mono, Core, Framework). It is unsafe to ignore.
Solution: Use Implicit (Public) Implementation
The recommended fix (as suggested by the compiler) is to switch to Implicit (Public) implementation.
When you declare the method as public, you satisfy both interface requirements simultaneously with a single method. Since both interface members map to the same signature, one public method handles both perfectly.
Solution: remove the interface name prefix and make the method public.
interface ITest<T>
{
void Test(T t);
void Test(int i);
}
public class Implementation : ITest<int>
{
// ✅ Correct: A public method satisfies both interface members.
// Both 'void Test(T)' (where T is int) and 'void Test(int)'
// will point to this logic.
public void Test(int arg)
{
System.Console.WriteLine("Processing int");
}
}
public class Program
{
static void Main()
{
Implementation impl = new Implementation();
// Works directly
impl.Test(5);
// Works via interface
((ITest<int>)impl).Test(5);
}
}
If you absolutely must implement them explicitly (perhaps to hide them from the public API), the only other solution is to change the Interface definition (e.g., rename one of the methods), which is not always possible if you don't own the interface code.
Conclusion
CS0473 highlights a tricky edge case in C# generics.
- Identify the Collision: Look at the generic type you passed (e.g.,
int) and see if it makes one method signature look identical to another existing method in the interface. - Avoid Explicit Implementation: Do not use
void Interface.Method(). - Use Public Implementation: Use
public void Method()to safely satisfy all matching interface members at once.