What is the precedence when more than one method overload matches?

Jawahar

I am trying understand OOP concepts in C#.

In the following sample code:

  1. why the ins1 prefers generic method
  2. why the ins2, ins3 prefers non-generic method

Note:when I comment out either of the "MyTestMethod" method, still the program continues to run successfully. This snippet is not something from production. This is just my training sample. So, please do not mind the naming conventions and standards.

using System;

namespace ConsoleApplication1
{
    class Program
    {
        public static void MyTestMethod(J input)
        {
            Console.WriteLine($"Program.MyTestMethod: {input.Val}");
        }
        public static void MyTestMethod<T>(T input) where T : J
        {
            Console.WriteLine($"Program.MyTestMethod<T>: {input.Val}");
        }

        static void Main(string[] args)
        {
            J2 ins1 = new J2(1);
            MyTestMethod(ins1);

            J ins2 = new J(2);
            MyTestMethod(ins2);

            J ins3 = new J2(3);
            MyTestMethod(ins3);

            Console.ReadKey();
        }
    }
    internal class J
    {
        public int Val { get; set; }
        public J(int i)
        {
            Console.WriteLine($"concrete base {i}");
            Val = i;
        }
    }
    internal class J2 : J
    {
        public J2(int i) : base(i * -1)
        {
            Console.WriteLine($"concrete {i}");
        }
    }
}
Jon Skeet

Section 7.5.3.2 of the C# specification is the relevant part here - "Better function member".

The result is more simply demonstrated as:

using System;

class Test
{
    static void Foo<T>(T item)
    {
        Console.WriteLine("Generic");
    }
    
    static void Foo(object x)
    {
        Console.WriteLine("Non-generic");
    }
    
    static void Main()
    {
        Foo(new object()); // Calls Foo(object)
        Foo("test"); // Calls Foo<T>(T)
    }
}

In both calls, both overloads are applicable function members. In picking which overload to call, the compiler first checks which conversion from argument type (or expression) to parameter type is "better".

When the type of the argument is object, T is inferred to be object as well, and so for both candidates the conversion is the identity conversion of object to object. At that point, the tie-breaking rules of 7.5.3.2 get involved, and the first one is:

If MP is a non-generic method and MQ is a generic method, then MP is better than MQ.

So that's why the non-generic overload is picked in that case.

When the argument is of type string, T is inferred to be string, so we have to compare the conversion from string to string (for the generic method) to the conversion from string to object (for the non-generic method). Here section 7.5.3.3 of the C# spec comes in, which starts:

Given an implicit conversion C1 that converts from an expression E to a type T1, and an implicit conversion C2 that converts from an expression E to a type T2, C1 is a better conversion than C2 if at least one of the following holds:

  • E has a type S and an identity conversion exists from S to T1 but not from S to T2

In this context, E is the expression "test", S is the type string, T1 is the type string, T2 is the type object, and so the conversion from string to string is deemed better - and the generic method is picked.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

What if more than one regular expression matches a prefix of the remaining input?

More than one operator overload in Rust

more than one operator "[]" matches these operands

What happens when there are more than one @JmsListener in an application? (in terms of concurrency)

What to do when searching on more than one word with django filter

No overload for method matches delegate?

C++ more than one instance of overloaded function matches the argument list when creating a header file

Excel Conditional Formatting: Highlight Duplicates When More than One Row Matches

Where does API Gateway direct when more than one pattern matches?

Reusing one method with more than one property

Maya Python, Renaming joints: more than one object matches name

Find where column matches more than one in another column

Zend Framework - More than one record matches the supplied identity

Workspace Authentication: More than one token matches the criteria

How to use an array in more than one method

Can a method return more than one value?

method to return more than one array

API HttpGet method with more than one parameters

How to create a hash / sha256sum in bash with more than one source / input and what is the best method?

When async block concurrency is more than one, what happens when exception is thrown?

java : Why the thread priority is not followed when there are more than one print statements in run method?

What do @mock.patch decorators do in Python when there are more than the number of parameters of the decorated method/function?

When we need more than one EntityManager?

What is the return type of a list when there is more than one bean alias in the Hibernate query?

What happens when a module is required by more than one file in Node.js?

What should I do when more than one submit cases exist

what will be happen when using more than one form tag in ASP.Net application?

How to determine mode for a number of date values and what to do when there is more than one mode

adding more than one value in replace method or split method