C# extension method overloading causes "missing assembly reference" error
c#, c#-5.0, extension-methods
Solution
From C# 5.0 spec, section 7.5.3:
Given the set of applicable candidate function members, the best function member in that set is located. If the set contains only one function member, then that function member is the best function member. Otherwise, the best function member is the one function member that is better than all other function members with respect to the given argument list, provided that each function member is compared to all other function members using the rules in §7.5.3.2.
Section 7.5.3.2:
Given an argument list A with a set of argument expressions { E1, E2, ..., EN } and two applicable function members MP and MQ with parameter types { P1, P2, ..., PN } and { Q1, Q2, ..., QN }, MP is defined to be a better function member than MQ if
• for each argument, the implicit conversion from EX to QX is not better than the implicit conversion from EX to PX, and
• for at least one argument, the conversion from EX to PX is better than the conversion from EX to QX.
There's no rule "if the argument type exactly matches the parameter type, pick that one" - so the compiler needs complete type information about all parameter types in order to be able to assess the above rules.
In order to resolve the issue without having to add a reference to `System.Net.Http`? You've already found the answer - use different method names. That let's you succeed because of the previously quoted part of 7.5.3:
If the set contains only one function member, then that function member is the best function member
Problem
There is a corresponding VS dev ticket https://connect.microsoft.com/VisualStudio/feedback/details/817276/error-cs0012-the-type-is-defined-in-an-assembly-that-is-not-referenced-issued-for-an-extension-method-that-is-not-used I have 2 extension methods: ``` public static class ExtensionMethods { public static string GetClientIpAddress(this HttpRequestBase request) { // ... } public static string GetClientIpAddress(this HttpRequestMessage request) { // ... } } ``` Class `HttpRequestMessage` is located in `System.Net.Http` assembly and `HttpRequestBase` is in `System.Web` (i.e. in different assemblies). The class `ExtensionMethods` is located in lets say ProjectA. This project compiles well and has no issues. Then I use the first method `GetClientIpAddress(this HttpRequestBase request)` from another project (lets say ProjectB), like this: ``` public override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); var sessionContext = DependencyResolver.Current.GetService<ISessionContext>(); // Call to GetClientIpAddress sessionContext.ClientIpAddress = filterContext.HttpContext.Request.GetClientIpAddress(); } ``` The ProjectB already has a reference to `System.Web`, but when I try to compile it, it causes an compiler error: The type '`System.Net.Http.HttpRequestMessage`' is defined in an assembly that is not referenced. You must add a reference to assembly '`System.Net.Http, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a`'. What I dont understand is why should I add a reference to `System.Net.Http`. It seems that the compiler tries to use the second method `GetClientIpAddress(this HttpRequestMessage request)` and this causes a missing reference to the assembly. Is this a bug? When I rename the first method (i.e. get rid of overloads) everything compiles well.