When you call a method in code, the compiler will try to find that method provided the argument list you pass (if any). Take this method:
public static void M(int i) { }
You can call it using M(42)
and all is well. When there are multiple candidates:
public static void M(byte b) { }
public static void M(int i) { }
The compiler will apply "overload resolution" to determine "applicable function members", and when more than one, the compiler will calculate the "betterness" of the overloads to determine the "better function member" that you intend to call.
In the case of the above example, M(42)
, the int
overload is chosen because non-suffixed numeric literals in C# default to int
, so M(int)
is the "better" overload.
(All parts in "quotes" can be looked up in the C# language specification, 12.6.4 Overload resolution.)
Now onto your code.
Given the literal 100
could be stored in both a byte
and an int
(and then some), and your second argument doesn't match either overload, the compiler doesn't know which overload you intend to call.
It has to pick any to present you with an error message. In this case it appears to pick the first one in declaration order.
Given this code:
public static void Main()
{
int? i = null;
M(100, i);
}
public static void M(int i, int i2) {}
public static void M(byte b, byte b2) {}
It mentions:
cannot convert from 'int?' to 'int'
If we swap the method declarations:
public static void M(byte b, byte b2) {}
public static void M(int i, int i2) {}
It complains:
cannot convert from 'int?' to 'byte'