【问题标题】:Not able to understand output of methods with Optional Parameter无法理解带有可选参数的方法的输出
【发布时间】:2015-06-22 08:48:20
【问题描述】:

今天我在写一个小程序来了解C#可选参数的基础知识。

以下是程序:

abstract class AbstractClass
{
    internal abstract void Test();
}

sealed class DerivedClass : AbstractClass
{        
    internal override void Test()
    {
        Console.WriteLine("In override DerivedClass.Test() method");
    }

    internal void Test(int a = 1)
    {
        Console.WriteLine("In DerivedClass.Test(int a=1) method " + a);
    }

    internal void Test(int b, int a = 1)
    {
        Console.WriteLine("In DerivedClass.Test(int b, int a=1) method " + string.Format("{0} {1}", b, a));
    }
}

这就是我调用Test()方法的方式:

   DerivedClass d = new DerivedClass();       
   d.Test();
   d.Test(6);
   d.Test(b:7);

输出:

在 DerivedClass.Test(int a=1) 方法 1

在 DerivedClass.Test(int a=1) 方法 6

在 DerivedClass.Test(int b, int a=1) 方法 7 1

关于d.Test();:我的理解是,它将Test()视为带有可选参数的方法,并使用此输出调用Test(int a = 1)

在 DerivedClass.Test(int a=1) 方法 1

但这就是在执行d.Test(6); 时让我感到困惑的地方:为什么这个方法调用没有给出如下输出:

在 DerivedClass.Test(int b, int a=1) 方法 6 1

根据我的理解,“6”是强制参数,它应该调用

internal void Test(int b, int a = 1)

请解释我的理解有什么问题。

还有如何调用被覆盖的方法?

internal override void Test()

【问题讨论】:

  • 为什么Test(6) 应该调用Test(int b, int a = 1)?已经有一个匹配方法Test(int a = 1),调用时将a设置为6
  • 请参阅"Should questions include “tags” in their titles?",其中的共识是“不,他们不应该”!
  • @Dennis_E 但是为什么在第一种情况下调用Test(int a = 1),而没有任何参数的匹配更好?
  • @HimBromBeere 我错过了(你说混淆是d.Test(6))。这是因为编译器更喜欢在类本身而不是基类中声明的方法。因此,它选择具有默认参数的那个。 C# 方法重载决议有时可能很复杂,有时可能会做与我们预期不同的事情。 (顺便说一句,我删除了我之前的评论)。

标签: c# .net overloading optional-parameters overriding


【解决方案1】:

internal void Test(int a = 1) 的规则匹配与您的代码 d.Test(6); 最佳匹配:它匹配参数的数量和类型。这使得该方法成为最佳匹配。

当调用d.Test(b:7); 时,您强制它作为最后一个方法运行,因为您匹配的是参数名称。这使得最后一种方法最匹配。

第一个 (d.Test();) 与您期望的方法 (void Test()) 不匹配,因为“自己的”方法优于派生方法。尝试移除基类或在方法上使用new 运算符,您会看到。

【讨论】:

    【解决方案2】:

    关于可选参数的规则可能有点混乱,但要记住的一个简单的经验法则是,它总是会使用参数较少的方法而不是参数较多的方法。

    所以

    d.Test(6);
    

    只有一个参数的方法:

    internal void Test(int a = 1)
    

    将被使用,即使它是一个可选参数。

    【讨论】:

    • 您能否提供一些与此相关的文档?命名和可选参数上的 MSDN 页面对我来说似乎不是很清楚。
    猜你喜欢
    • 1970-01-01
    • 2013-08-11
    • 2016-12-15
    • 1970-01-01
    • 1970-01-01
    • 2015-03-15
    • 1970-01-01
    • 1970-01-01
    • 2017-09-02
    相关资源
    最近更新 更多