4

All classes that we create inherit from the Object class without needing to explicitly declare inheritance to that class.

  • How does Microsoft can make all .NET class implicitly inherit from the Object class?
  • Does the compiler inject that inheritance behind the scenes?
  • Can I do the same kind of thing: make all my classes inherit implicitly from a class interface for example?

My question may be ambiguous so I will clarify:

I'm not asking about inheriting from another class other than Object since I know that multiple inheritance for classes is forbidden. I'm talking about inheritance rather through class Interfaces, my question is about IMPLICITLY DOING IT not about substituting an object by another class of my own, or do multiple inheritance with Object and another class of my own. I want to get all classes inherit form Interface1OfMyOwn and Interface2OfMyOwn.

4

4 回答 4

11

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

问他们是如何实现的,就像问他们是如何实现一个void方法不返回数据的事实,或者他们是如何实现类具有属性的事实:它只是在编译器代码中的某个地方(这里可能是 C# 编译器或 JIT 编译器)。我们无法确定,但可以说,每当编译器没有检测到类中的显式继承时,它就会选择System.Object替代,就这么简单。所以你必须接受这Object只是编译器的一种特殊类型

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

(当然,如果你想隐式实现一个接口,也会发生同样的情况:所有没有真正实现该接口的类都会中断并导致编译错误。或者,如果你不走运,接口会匹配不相关的方法碰巧具有匹配签名并导致您通过测试发现的奇怪行为的类。)

于 2013-05-26T11:57:32.890 回答
6

这在运行时的非常低级别上得到支持,值类型的值可以嵌入到存储在垃圾收集堆上的对象中。从而将值类型转换为引用类型,并创建每个值类型都继承自 ValueType 和 Object 的错觉。哪些是引用类型。

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

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

于 2013-05-26T12:29:40.340 回答
3

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

您可以使用MS的 Roslyn 项目对编译过程进行非常深入的控制,但请注意,Roslyn 仍未“准备好生产”。

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

另一个值得研究的选项可能是 AOP - 有一些 .NET 框架可以做一些令人惊奇的事情(例如,请参见此处)。

于 2013-05-26T13:06:15.887 回答
1

对于您想要的,扩展方法object起作用。您还可以使用泛型类型,它会立即丢失更少的类型信息。

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");
    }

}
于 2015-02-18T14:25:21.627 回答