Microsoft如何使所有.NET类隐式继承自Object类?我可以做同样的事情吗?

时间:2013-05-26 11:44:53

标签: c# .net inheritance

我们创建的所有类都继承自Object类,而不需要显式声明该类的继承。

  • Microsoft如何使所有.NET类隐式继承 Object类?
  • 编译器是否注入了该继承 场景?
  • 我可以做同样的事情:做我所有的课程 从类接口隐式继承,例如?

我的问题可能含糊不清,所以我会澄清:

我不是要求继承自Object以外的其他类,因为我知道禁止对类进行多重继承。我正在谈论继承,而不是通过类接口,我的问题是关于隐含地做的不是用我自己的另一个类替换一个对象,或者用Object和我自己的另一个类做多重继承。我希望所有类都继承自Interface1OfMyOwn和Interface2OfMyOwn。

4 个答案:

答案 0 :(得分:11)

所有类都隐式扩展Object,因为C#标准指定了语言。

询问他们如何实现这就像询问他们如何实现void方法不返回数据的事实,或者他们如何实现类具有属性的事实:它只是编译器代码中的某个地方(这里可能是C#编译器或JIT编译器)。我们无法确切地知道,但是有理由说,只要编译器没有在类中检测到显式继承,它就会改为System.Object,就像那样简单。因此,您必须接受Object只是编译器的特殊类型

为什么你不能用自定义类做到这一点似乎显而易见:它会使编译器彻底混淆没有显式继承的类是应该扩展Object还是你的自定义类。如果它为没有显式继承的每个类选择后者,那么在大多数情况下会引入编译错误,或者,如果你特别不走运,那么只会在运行时出现的令人惊讶的行为。如果它选择了前者,你必须明确选择你的课程,那有什么意义呢?

(当然,如果你想隐式实现一个接口,就会发生这种情况:所有没有真正实现该接口的类都会破坏并导致编译错误。或者,如果你运气不好,界面会匹配类中不相关的方法恰好具有匹配的签名并导致您通过测试发现的奇怪行为。)

答案 1 :(得分:6)

这在运行时内的非常低级别受支持,值类型的值可以嵌入存储在垃圾收集堆中的对象中。因此,在引用类型中转换值类型并创建每个值类型从ValueType和Object继承的错觉。哪些是参考类型。

该机制在.NET中调用装箱,值类型值字面上被“装箱”到一个对象中。还有一个取消装箱转换,从带有框值的对象返回到值类型的值。 C#编译器将根据您的源代码自动发出这些转换。有专门的操作码是IL,C#编译器从源代码中发出的中间语言。分别是Opcodes.Box和Opcodes.Unbox指令。 Opcodes.Constrained是一个可以优化转换的指令。抖动知道如何实现它们并生成非常有效的内联机器代码来进行这些转换。

Boxing是System.Object的高度特定,它是类型层次结构中的基类,支持它的管道特定于值类型值。它不是可扩展的机制,您不能添加自己的IL指令也不能扩展抖动,也不能为C#语言提供新的语法。如果您需要类型具有公共基本接口或类,则必须在代码中以这种方式声明它们。 动态关键字可能对您有吸引力,但问题并不清楚。

答案 2 :(得分:3)

我完全赞同所提供的两个答案...只是想添加一个选项,你可以做些什么来实现预期的结果,即“自动继承自定义接口”:

您可以使用Roslyn project from MS对编译过程进行非常深入的控制,但要注意Roslyn仍然没有“生产就绪”。

您可以编写一些代码来影响编译过程并分析甚至更改编译器如何工作以实现您想要的目标。

值得关注的另一个选择可能是AOP - 有一些.NET框架可以做出惊人的事情(例如参见here)。

答案 3 :(得分:1)

对于您想要的内容,object上的Extension Methods将有效。您也可以使用泛型类型,它会立即丢失较少的类型信息。

static class GeneralMethods
{
    public static void Testing(this object This)
    {
        This.ToString().Dump("Testing");
    }

    public static void Test2<T>(this T This)
    {
        This.Dump("Test2");
    }

}