我已经编程了5年前的第一个Delphi和现在的c#所以我想我知道重载方法是如何工作的,但显然不是。
首先是一些代码
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
}
}
我已经为每次调用CreateSettings添加了一个数字,以便更容易解释。
我的问题是:
调用#1 调用CreateSettings的错误(通用)版本,因为我已经转换为byte
,但为什么?
通话#2 工作得很好。
通话#3 的效果也不错。我明确地调用了泛型版
拨打电话#4 也有效但有一些&#34;魔法&#34;编译器解析正确的(通用)版本并调用它。但为什么它有效呢?
我已经发现#1调用了错误版本的原因与#4的作用相同。我只是想知道是否有人可以给我一个解释。
答案 0 :(得分:10)
重载正如预期的那样工作,你声明:
#1调用了错误的版本
它会调用正确的版本,因为您正在做的是将int
投射到byte
,因此您不再拥有int
变量,你有byte
。你期望它与int
重载相匹配吗?怎么可能,你只是将变量转换为byte
。
呼叫#4也有效,但有一些“魔术”
这不是魔术,这基本上是因为与上述相同的原因,类型既不是int
也不是string
,所以它可以调用的唯一其他可能的重载是通用的,因为你的“通用”方法基本上是说任何其他类(这里的类型是TestEnum
)
答案 1 :(得分:2)
调用的方法由重载决策的过程决定。
编译器根据传递的参数类型构建可能的候选方法列表,然后根据一组规则对它们进行排序,这些规则确定哪种方法是根据可能发生的任何类型转换。您可以在此处查看这些规则:
https://msdn.microsoft.com/en-us/library/aa691339%28v=vs.71%29.aspx
此处描述了一般的重载解析过程:
https://msdn.microsoft.com/en-us/library/aa691336%28v=vs.71%29.aspx
通过遵循这些规则并与每个场景进行比较,您应该能够看到每种情况下您要遵循的规则。
答案 2 :(得分:1)
致电#1
你在TEnum:struct,IComparable,IFormattable
中做了一个约束这意味着TEnum类型是值类型或实现两个接口的类型 你有一个byte参数,这意味着将被调用的方法是方法1,因为byte是一个值类型,其他方法都没有接受byte作为参数
致电2 和致电3
按预期工作
<强> Call4 强>
编译器再次解析为第一个方法,因为Enum是一个值类型,而另一个方法都没有接受Enum类型作为参数,所以最合适的重载是方法1