Inheritance of extension methods

How inheritance works with extension methods in C #.

Suppose you have interfaces IA , IB : IA and IC , and the class Foo : IB, IC , extension methods are now defined:

 public static class Extensions { public static void Bar (this IA instance) { //Some code } public static void Bar (this IB instance) { //Some code } public static void Bar (this IC instance) { //Some code } public static void Bar (this Foo instance) { //Some code } } 

How does the compiler determine the behavior of Foo.Bar() ? Based on empirical tests, the compiler always selects the most specific instance (for example, a regular call) and does not use dynamic binding (since the this annotation) is more β€œsyntactic” sugar, I suppose ...

If two or more classes define a method from different branches in the inheritance hierarchy, the call is ambiguous. Is there a way to prioritize one method over another in such cases?

Are the statements above correct?

+6
source share
1 answer

Inheritance matters, but the main thing is the namespace, from C# spec:

if normal call processing does not apply methods, an attempt is made to process the construct as an extension of the method call.

The exact process and example can be found in the C# specification, 7.6.5.2 Extension method invocations . The resolution process (where C is the set of possible type permissions and M is the set of extension methods):

Search C continues as follows:
β€’ Starting from the closest namespace-encompassing declaration, continuing with each closing namespace declaration and ending with the compiling unit, successive attempts are made to find a set of candidates extension methods:

o If a given namespace or compilation unit directly contains declarations of a non-common Ci type with suitable extension methods Mj, then the set of these extension methods is a candidate set.

o If namespaces are imported using namespace directives in a given namespace or in a compilation block of a declaration not of general Ci type with suitable extension methods Mj, then the set of these extension methods is a set of candidates.

β€’ If no candidate set is found in any namespace or compilation declaration, a compile-time error occurs.

β€’ Otherwise, the congestion authorization applies to the recruitment of candidates as described in (Β§7.5.3). If no best method is found, a compile-time error occurs.

β€’ C is the type in which the best method is declared as an extension of the method. Using C as a target, a method call is then processed as a call to a static method (Β§7.5.4).

Which, if I understand it correctly, means that it chooses the best extension method in the nearest namespace at compile time. It is very important to understand that there is no dynamic call, resolution is done statically (i.e., in compiletime).

+4
source

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


All Articles