Overloading the C # extension method raises an "Missing assembly reference" error

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) { // ... } } 

The HttpRequestMessage is in the System.Net.Http assembly and the HttpRequestBase is in System.Web (that is, in different assemblies). The ExtensionMethods class is in the let ProjectA file.

This project compiles well and has no problems.

Then I use the first GetClientIpAddress(this HttpRequestBase request) method GetClientIpAddress(this HttpRequestBase request) from another project (e.g. ProjectB ), for example:

 public override void OnActionExecuting(ActionExecutingContext filterContext) { base.OnActionExecuting(filterContext); var sessionContext = DependencyResolver.Current.GetService<ISessionContext>(); // Call to GetClientIpAddress sessionContext.ClientIpAddress = filterContext.HttpContext.Request.GetClientIpAddress(); } 

ProjectB already has a link to System.Web , but when I try to compile it, it causes a compiler error:

The type ' System.Net.Http.HttpRequestMessage ' is defined in an assembly that is not referenced. You must add a reference to the assembly ' System.Net.Http, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a '.

What I do not understand, why should I add a link to System.Net.Http .

It seems that the compiler is trying to use the second method GetClientIpAddress(this HttpRequestMessage request) , and this leads to the absence of a reference to the assembly. This is mistake?

When I rename the first method (i.e. get rid of overloads), everything compiles well.

+4
source share
2 answers

From the C # 5.0 specification, section 7.5.3:

Given the set of applicable candidate candidate elements, the best member of the function in this set is found. If a collection contains only one member of a function, then this member of the function is the best member of the function. Otherwise, the best member of the function is one member of the function, which is better than all the other members of the function with respect to this list of arguments, provided that each member of the function is compared with all other members of the function using the rules in section 3.7.3.2.

Section 7.5.3.2:

Given a list of arguments A with a set of argument expressions {E 1 , E 2 , ..., E N } and two applicable functional elements M P and M Q with parameter types {P 1 , P 2 , ..., P N } and {Q 1 , Q 2 , ..., Q N }, M P is defined as a better member of the function than M Q if

โ€ข for each argument, the implicit conversion from E X to Q X is not better than the implicit conversion from E X to P X and

โ€ข for at least one argument, the conversion from E X to P X is better than the conversion from E X to Q <sub> X sub>.

There is no rule "if the type of the argument exactly matches the type of the parameter, select it" - so the compiler needs complete information about the type of all types of parameters in order to be able to evaluate the above rules.

To solve the problem without adding a link to System.Net.Http ? You have already found the answer - use different method names. This will allow you to succeed due to the previously cited part of 7.5.3:

If a collection contains only one member of a function, then this member of the function is the best member of the function.

+6
source

I also did a simple test without extension methods and got the same effect. As Damien_The_Unbeliever said, the problem is only with method overloading.

0
source

Source: https://habr.com/ru/post/1490464/


All Articles