C# 7.2 - "In" Parameter Method Overloading Tiebreaker

This article explains the “in” parameter method overloading with Visual Studio 2017 Version 15.6. Preview 2.

This article explains the “in” parameter method overloading with Visual Studio 2017 Version 15.6. Preview 2.

The new version of Visual Studio 2017 (Version 15.6 Preview 2.0) was announced on January 10,  2018. In this version, one tiebreaker change has been done for C# Compiler which allows method calling without any conflict for the scenarios where we have multiple method overloads that differ only in parameter modifiers keywords like ‘in’.

Before jumping to the actual change, let’s try to understand the problem.

We know that we can define an overloaded method using parameter modifiers ‘in’, ‘out’ or ‘ref’. Thus, the following code is valid.

  1. public void DoSomething(int x) { }  
  2. public void DoSomething(ref int x) { }  

But the below code snippet will give an error.

  1. public void DoSomething(int x) { }  
  2. public void DoSomething(in int x) { }  
  3. public void DoSomething(out int x) { x = 20; }  
  4. public void DoSomething(ref int x) { }  

Error 1

'Program' cannot define an overloaded method that differs only on parameter modifiers 'out' and 'in'

Error 2

'Program' cannot define an overloaded method that differs only on parameter modifiers 'ref' and 'in' 

So far, we have seen how overloading can be done using ‘in’, ‘out’ and ‘ref’ keyword. Now, let’s concentrate only on ‘in’ parameter.

While calling the method, “in” keyword is optional. Have a look at the following 2 code snippets.

Code Snippet 1

  1. class Program  
  2. {  
  3.     static void Main(string[] args)  
  4.     {  
  5.         Program program = new Program();  
  6.         int number = 50;  
  7.         program.DoSomething(number);  
  8.     }  
  9.      
  10.     public void DoSomething(in int x)  
  11.     {  
  12.   
  13.     }  
  14. }  

Code Snippet 2

  1. class Program  
  2.     {  
  3.         static void Main(string[] args)  
  4.         {  
  5.             Program program = new Program();  
  6.             int number = 50;  
  7.             program.DoSomething(in number);  
  8.         }  
  9.          
  10.         public void DoSomething(in int x)  
  11.         {  
  12.   
  13.         }  
  14.     }  

As you can see in “Code Snippet 1”, I am calling DoSomething() method without “in” keyword and in “Code Snippet 2” calling DoSomething() method with “in” keyword. However, both are calling the same method.

public void DoSomething(in int x){}

Now, overload the DoSomething() method add one more DoSomething() method in code snippet 2 as shown in the following code snippet. 

Code Snippet 3

  1. class Program  
  2.     {  
  3.         static void Main(string[] args)  
  4.         {  
  5.             Program program = new Program();  
  6.             int number = 50;  
  7.             program.DoSomething(in number);  
  8.         }  
  9.          
  10.         public void DoSomething(in int x)  
  11.         {  
  12.   
  13.         }  
  14.   
  15.         public void DoSomething(int x)  
  16.         {  
  17.   
  18.         }  
  19.     }  

Still, there is no issue, and you can compile this program successfully. Now, remove the “in” keyword from the calling method and try to call the overloaded DoSomething() method.

Before Visual Studio 2017 15.6 Preview 2, you will get the following error:

The call is ambiguous between the following methods or properties: 'Program.DoSomething(in int)' and 'Program.DoSomething(int)'

C#
Screenshot from Visual Studio 2017 Version 15.5.3 

Now, run the code with Visual Studio 2017 Version 15.6 Preview 2, and you can see that it gets compiled successfully.

C#
Screenshot from Visual Studio 2017 Version 15.6 Preview 2

Thus, we can say that the tiebreaker change has been implemented and now it will work more efficiently. In the above screenshot, we are not passing in keyword so it will call the method

public void DoSomething(int x) { }

However, it does not mean that “in” parameter is not optional. “In” parameter is still optional insofar as there is no other matching overloaded method available.

In this article, I have just explained the tiebreaker change for “in” parameter; if you would like to explore more about “in”, “out” & “ref”, then please go through these articles.

Explore more about C# latest features,