为什么C#中的大多数类型都继承自System.Object? [重复]

问题描述

|                                                                                                                   这个问题已经在这里有了答案:                                                      

解决方法

        了解值类型和引用类型之间的差异非常重要。区别的核心是类型表达式的值是多少。 考虑:
int x = 10;
SomeClass y = new SomeClass();
此处,
x
的值实际上是10-10的位最终出现在与变量ѭ1associated相关的存储器中。
y
的值是一个参考-一种访问内存中单独对象的方式。 当您使用赋值时,区别变得非常重要,尤其是对于可变引用类型:
int x1 = 10;
int x2 = x1;
SomeClass y1 = new SomeClass();
SomeClass y2 = y1;

y1.SomeProperty = \"Fred\";
Console.WriteLine(y2.SomeProperty);
在这两种情况下,变量的值都复制到赋值中-因此
x2
的值为10;
y2
的值是对同一对象的引用。因此,当通过倒数第二个属性修改对象的数据时,仍可以通过
y2
看到该差异。 当
z1
是值类型的变量时,几乎不会写
z1.SomeProperty = ...
,因为大多数值类型都是不可变的。 (您不能更改数据本身的值-您必须为该变量显式分配一个新值。)如果这样做,您将看不到通过先前使用赋值ѭ9初始化的变量的任何更改。因为该值将在该分配中复制。 我有一篇关于值类型和引用类型的文章,其中对此进行了更详细的介绍。 现在,C#和.NET具有统一的类型系统,即使值类型也从ѭ11继承。这意味着您可以在值类型值上调用
Object
中的所有消息。有时这需要装箱(将值类型的值转换为
Object
),有时则不需要...我现在不会讨论所有规则。重要的是,如果值类型覆盖对象方法(例如
ToString
GetHashCode
),则无需在框内插入值即可调用该方法。 虽然拳击确实会降低性能,但根据我的经验,它通常被夸大了。如今,对于泛型来说,装箱确实并没有以前那么多了,但是,只要您明智地使用它,就不太可能在您的应用程序中成为严重的性能问题。 编辑:关于游戏,性能和一次学习的东西... 我见过很多人在不了解基本知识的情况下就一个相对高级的主题提出问题。显然,初学者没错,但是在我看来,在“新手友好”的环境中首先学习基础知识非常重要-我认为游戏不算什么。 我个人认为控制台应用程序是学习大多数核心新概念的最简单方法-不管是语言功能,文件IO,集合,Web服务,线程等等。显然,对于“学习Windows窗体”之类的东西,您可以\使用控制台应用程序无法做到这一点-但是,如果您对Windows Forms以外的其他任何东西都不陌生,那确实有帮助。 因此,我强烈建议您在进入游戏之前学习C#的基础知识,例如值类型和引用类型的工作方式,参数传递的工作方式,泛型,类,继承等。这听起来像是额外的工作,但很可能会节省您以后的时间。当某些事情表现不正常时,您将了解该语言的工作原理,因此您可以专注于API的行为方式等。尝试一次学习一件事可以使整个过程变得更加顺畅。我的经验。 特别是,游戏的性能要求意味着有时值得编写非常惯用的C#。诸如预分配对象并在通常创建新对象的地方重用它们之类的事情……甚至创建可变的结构,我在正常开发中几乎都做不到。在关键的游戏循环中,完全装箱或创建任何对象可能不是一个好主意-但这并不意味着这些东西在正常的参考范围内都是“昂贵的”。了解何时合适这些条件以及何时不合适这些条件是非常重要的……并且,如果您从游戏开发开始,您将对这些东西有一个不平衡的看法,IMO。您也可能会尝试对真正不需要的地方进行微优化-但是,如果您以C#和.NET扎根,那么您将处在一个更好的位置的角度来看。     ,只要所有对象似乎都源自
System.Object
,那么出于所有实际目的,它们都源自
System.Object
。在引擎盖下,事物进行了优化,以使so18大部分时间仅是四字节ѭ18,但是当它需要成为对象时它就是对象。这就是拳击的全部内容。 编译器和运行时都非常非常努力地确保原始类型不会因过多的大小或功能负担而负担过多。同时,确保满足C#规范和对象层次结构所需的所有规则。有时编译器采用快捷方式,有时运行时可以完成工作。     ,        拥有通用基类的一个优势意味着您可以编写类似 公共无效DoSomething(对象对象) { .... } 并基本上传递任何东西。 虽然不确定性能方面。     ,        编辑:为了阐明我对拳击的立场:乔恩在他要我指出时说得很好:“ [拳击与创建任何其他小物体一样贵”。因此,我并不是要夸大性能影响。但是,我确实打算为聪明的读者提供他们根据个人情况做出明智决定所需的信息。 编辑:好的,所以如果您想成为技术专家,我会撤回我以前的声明。根据C#ECMA标准:\“所有值类型都隐式继承自类对象。任何类型都不能从值类型派生,因此值类型被隐式密封(第17.1.1.2节)。\”(C#ECMA标准第130页)但是...据我了解,OP问题的重点实际上与性能以及.NET中如何处理类型有关。到此为止:值类型与引用类型的处理方式有所不同-简单类型(int,float等)的存储和有效处理方式。当它们被当作对象对待时,您将付出昂贵的性能成本(正如OP所怀疑的)。对于我来说,这个故事的寓意是,也许希望其他人的意思是,避免装箱-实际上,这意味着值类型不同于对象...您可能会回答我。 你误会了。 System.Integer和System.Float不是System.Object的子类。它们就是所谓的“值类型”。 您可以在文档中看到这是正确的:http://msdn.microsoft.com/zh-cn/library/system.int32.aspx,其中显示Int是\“ struct \”。 本文详细讨论了该主题:http://msdn.microsoft.com/zh-cn/library/34yytbws%28v=vs.71%29.aspx 如果您对此感兴趣,则一定要读完最后一篇。 关于更广泛的问题,“为什么C#中的大多数类型都是从System.Object继承的”,您会发现这没有什么独特之处。 Java具有java.lang.Object,Objective-C具有NSObject等。等等。值类型和引用类型之间的区别几乎是通用的。我不确定我是否真的需要对此进行冗长的回答,因为我认为指出差异之处以及有关C#中的值类型的文章可能已经回答了您的问题。 为了阐明其他人对拳击等的问题:http://msdn.microsoft.com/en-us/magazine/cc301569.aspx