当前位置: 首页 > 知识库问答 >
问题:

显式地将派生类标记为基类的实现接口

楚天宇
2023-03-14
interface IBase
{
    string Name { get; }
}

class Base : IBase
{
    public Base() => this.Name = "Base";
    public string Name { get; }
}

class Derived : Base//, IBase
{
    public Derived() => this.Name = "Derived";
    public new string Name { get; }
}


class Program
{
    static void Main(string[] args)
    {
        IBase o = new Derived();
        Console.WriteLine(o.Name);
    }
}

在这种情况下,输出将是“base”。

如果我明确地声明派生实现了IBase(实际上已经由基类base实现了,这样的注释似乎没有用),那么输出将是“派生的”

class Derived : Base, IBase
{
    public Derived() => this.Name = "Derived";
    public new string Name { get; }
}

这种行为的原因是什么?

VS 15.3.5,C#7

共有1个答案

顾穆冉
2023-03-14

在C#5规范的第13.4.4至13.4.6节中对其进行了解释。下面引用了相关的部分,但基本上,如果您显式地声明一个类实现了一个接口,这将再次触发接口映射,因此编译器将该类作为用来计算每个接口成员映射到哪个实现的类。

13.4.4接口映射

类或结构必须提供该类或结构的基类列表中列出的所有接口成员的实现。在实现类或结构中定位接口成员实现的过程称为接口映射。

    null

...

13.4.5接口实现继承

继承其基类提供的所有接口实现。如果不显式地重新实现接口,派生类就不能以任何方式更改它从基类继承的接口映射。例如,在声明中

interface IControl
{
    void Paint();
}
class Control: IControl
{
    public void Paint() {...}
}
class TextBox: Control
{
    new public void Paint() {...}
}
Control c = new Control();
TextBox t = new TextBox();
IControl ic = c;
IControl it = t;
c.Paint();            // invokes Control.Paint();
t.Paint();            // invokes TextBox.Paint();
ic.Paint();           // invokes Control.Paint();
it.Paint();           // invokes Control.Paint();
interface IControl
{
    void Paint();
}
class Control: IControl
{
    void IControl.Paint() {...}
}
class MyControl: Control, IControl
{
    public void Paint() {}
}

controlicontrol.paint映射到control.icontrol.paint并不影响在mycontrol中的重新实现,后者将icontrol.paint映射到mycontrol.paint

 类似资料:
  • 我正在学习一本书,即“.NET域驱动的C#设计”。 问题基于如下类图所示的场景: 图:http://screencast.com/t/a9uuljvw0 现在,如果我用ICompanyRepository变量comrep调用Add()函数... 然后调用RepositoryBase类(它是CompanyRepository的父类)中的Add()函数。 我的问题是:在(抽象基)类“repositor

  • 我正在创建一个带有属性的抽象基类,并在派生类中继承该基类。派生类继承基类和接口。当我试图使用接口引用派生类的对象时,我看到基类的属性也没有在派生类接口中声明。原始代码有点大,但下面是我所遵循的相同方法 基类: 调试器详细信息 多谢.

  • 问题内容: 我需要扩展Networkx python包,并为我的特殊需求向类添加一些方法 我想到的方法是简单地派生一个新的类say ,并添加所需的方法。 但是,networkx中还有其他几个函数可以创建和返回对象(例如,生成随机图)。现在,我需要将这些对象转换为对象,以便可以使用新方法。 最好的方法是什么?还是我应该以完全不同的方式解决问题? 问题答案: 如果您只是添加行为,而不依赖于其他实例值,

  • 尽管派生类对象也是基类对象,但是派生类类型和基类类型是不同的。在 public 继承中,派生类对象能作为基类对象处理。由于派生类具有对应每个基类成员的成员(派生类的成员通常比基类的成员多),所以把派生类的对象赋给基类对象是合理的。但是,反过来赋值会使派生类中基类不具有的成员没有定义,所以这是不允许的。尽管如此,提供正确的重载赋值运算符和(或)转换构造函数可以允许这种操作(见第8章)。 常见编程错误

  • 假设我有一个没有数据的类: 和派生类 Empty类的对象的大小为1。派生类的空部分的大小通常为0。据我所知,编译器看到基Empty类没有数据,因此它可以优化Empty的大小,以防它“在”Derived中,但标准并不要求这样做。 所以问题是: 我能在编译时确定Derived类的Empty部分并没有占用内存吗。 我知道我可以像一样进行检查...但它太冗长了,并且有几个类,如派生。有没有更优雅的解决方案