【问题标题】:Why call object class parameter method linseed of fixed data type parameter in inheritance [duplicate]为什么在继承中调用固定数据类型参数的对象类参数方法linseed [重复]
【发布时间】:2018-02-19 06:16:37
【问题描述】:

案例一:

public class BaseClass
{
    public virtual void Print(int i)
    {
        Console.WriteLine("BaseClass Print(int)");
    }
}

public class DerivedClass : BaseClass
{
    public override void Print(int i)
    {
        Console.WriteLine("DerivedClass Print(int)");
    }

    public void Print(object obj)
    {
        Console.WriteLine("DerivedClass Print(object)");
    }
}
static void Main(string[] args)
{
    DerivedClass objDerivedClass = new DerivedClass();
    int i = 10;
    objDerivedClass.Print(i);
}

输出是DerivedClass Print(object)

案例 2:

public class SomeClass
{
    public void Print(int i)
    {
        Console.WriteLine("DerivedClass Print(int)");
    }

    public void Print(object obj)
    {
        Console.WriteLine("DerivedClass Print(object)");
    }
}

static void Main(string[] args)
{
    SomeClass objSomeClass = new SomeClass();
    int i = 10;
    objSomeClass.Print(i);
}

输出是DerivedClass Print(int)

调用objDerivedClass.Print(i);方法后,输出为DerivedClass Print(object)。我不明白为什么要调用 Print(object obj) 方法而不是 Print(int i)

如果DerivedClass 不继承BaseClass 类,则输出为DerivedClass Print(int)

请解释......

【问题讨论】:

  • C# 语言规范的第 7.5.3 节是关于重载解决方案的,因此您应该参考它。鉴于这种行为,我会假设,如果有多个可能的候选者,则当前类型的成员优先于基类型的重载成员。这真的不是问题,因为如果参数是适当的类型,您总是可以编写重载来调用覆盖。

标签: c# inheritance overload-resolution


【解决方案1】:

这就是重载解析如何与继承一起工作:

  1. 包含override 修饰符的函数被排除在候选集之外。
  2. 由于可以使用带有object 参数的函数,因此从候选集合中删除基中声明的函数。

获胜者是带有object 参数的函数。

根据Eric Lippert (from Microsoft)

这是设计使然,并且有充分的理由。这种设计有助于防止脆性基类问题。 C# 旨在让编写“版本化”组件变得更容易、更安全,而这条规则是其中的重要组成部分。

当不使用继承时,这两个函数都是候选函数,并且使用更具体的一个。获胜者是带有int 参数的函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-29
    • 2016-02-19
    • 2019-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-13
    相关资源
    最近更新 更多