重载方法如何工作

时间:2015-04-21 08:51:32

标签: c# .net

我已经编程了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的作用相同。我只是想知道是否有人可以给我一个解释。

3 个答案:

答案 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