I've been programming for may years first Delphi and now c# so I thought I knew how overloaded method worked, but apparently not.
First some code
public enum TestEnum { Option1, Option2, Option3 }
public class Setting
{
public Setting()
{
AddSettings();
}
protected void CreateSetting<TEnum>(string AName, TEnum AValue) where TEnum : struct, IComparable, IFormattable
{
//do stuff
}
protected void CreateSetting(string AName, string AValue)
{
//do stuff
}
protected void CreateSetting(string AName, int AValue)
{
CreateSetting(AName, AValue.ToString());
}
protected void AddSettings()
{
CreateSetting("Language", (byte)0); //#1
CreateSetting("BFL", "true"); //#2
CreateSetting<TestEnum>("TestEnum", TestEnum.Option1); //#3
CreateSetting("TestEnum", TestEnum.Option1); //#4
}
}
I've added a number to each call to CreateSettings in order for making it easyer to explain.
My question as :
Call #1 calls the wrong (Generic) version of CreateSettings because I've made a cast to a byte
but why?
Call #2 works just fine.
Call #3 works just fine as well. I explicit calls the gerneric version
Call #4 also works but with some "magic" the compiler resolves the correct (genneric) version and calls that. But why does it work?
I have figured out that #1 call the wrong version for the same reason that #4 works. I was just wondering if any one could give me an explanation.
The overloads are working as expected, you stated that:
#1 calls the wrong version
It calls the correct version because what you're doing is casting the int
to a byte
, so you no longer have an int
variable, you have a byte
. Are you expecting it to match the int
overload? How could it, you've just cast the variable to a byte
.
Call #4 also works but with some "magic"
This isn't magic, this works basically because of the same reason as the above, the type is neither an int
or a string
, so the only other possible overload it could call is the generic one because your "generic" method essentially says any other class (the type here is TestEnum
)
The method called is determined by the process of overload resolution.
The compiler builds a list of possible candidate methods that could be called based on the types of the parameters passed, and then ranks them based on a set of rules that determine which method is the best option to call based on the quality of any type conversion that may occur. You can view these rules here:
https://msdn.microsoft.com/en-us/library/aa691339%28v=vs.71%29.aspx
The general overload resolution process is described here:
https://msdn.microsoft.com/en-us/library/aa691336%28v=vs.71%29.aspx
By following through these rules and comparing to each of your scenarios you should be able to see which rule you are hitting in each case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With