这个问题在这里已经有了答案:
Why does every class in .NET inherit from Object?
(9 个回答)
8年前关闭。
我正在检查 C# 中的 int 和 float 类型,甚至它们都有“ToString”等方法,这意味着它们是从 System.Object 继承的。但这不会导致性能下降吗?我知道由于性能原因,他们没有在 Java 中创建像 int 对象这样的基本类型。此规则是否也适用于 .NET?如果是这样,那是否意味着 .NET 比 Java 慢?但实际上这不是真的,因为我用 C# 编写的程序比我用 Java 编写的程序运行得更好。那么这里有什么我不明白的地方吗?
最佳答案
了解值类型和引用类型之间的差异非常重要。区别的核心是类型表达式的值是什么。
考虑:
int x = 10;
SomeClass y = new SomeClass();
这里,
x
的值确实是 10 - 10 的位最终出现在与变量 x
相关联的内存中.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.SomeProperty = ...
当z1
是值类型的变量,因为大多数值类型是不可变的。 (您不能更改数据本身的值 - 您必须显式地为变量分配一个新值。)但是,如果您这样做了,您将不会看到之前使用赋值 z1
初始化的变量的任何更改。因为该值会在该赋值中被复制。我有一个 article on value types and reference types更详细地介绍了所有这些。
现在,C# 和 .NET 有了统一的类型系统,甚至值类型都继承自
System.Object
.这意味着您可以调用来自 Object
的所有消息。关于值类型值。有时这需要装箱(将值类型值转换为 Object
),有时则不需要......我现在不会进入所有规则。重要的是,如果值类型覆盖了对象方法(例如 ToString
或 GetHashCode
),则不需要将值装箱以调用该方法。虽然拳击确实有性能损失,但它是 typically overstated in my experience .如今,对于泛型,实际上并不像以前那样需要拳击 - 但只要您明智地使用它,它就不太可能成为您的应用程序中的重大性能问题。
编辑:关于游戏、性能和一次学习一些东西......
我见过很多人在不了解基础知识的情况下就相对高级的主题提出问题。显然,作为初学者并没有错,但在我看来,首先在“新手友好”环境中学习基础知识非常重要——我认为游戏不算数。
就我个人而言,我发现控制台应用程序是学习大多数核心新概念的最简单方法——无论是语言特性、文件 IO、集合、Web 服务、线程等。控制台应用程序 - 但如果您对 Windows 窗体部分不陌生,它真的很有帮助。
所以我强烈建议你在进入游戏之前学习 C# 的基础知识——比如值类型和引用类型的工作原理、参数传递的工作原理、泛型、类、继承等。这听起来像是额外的工作,但它可能会为您节省以后的时间。当某些事情不像你期望的那样表现时,你会知道语言是如何工作的,所以你可以专注于 API 的不同行为等。根据我的经验,尝试一次学习一件事会使整个过程更顺畅.
特别是游戏的性能要求意味着有时编写非常不惯用的 C# 是值得的。诸如预先分配对象并在通常创建新对象的地方重用它们之类的事情……甚至创建我在正常开发中几乎从未做过的可变结构。在关键的游戏循环中,拳击或创建任何对象可能是一个坏主意 - 但这并不意味着这些东西在正常引用框架中“昂贵”。它是 真的很重要你知道这些东西什么时候合适,什么时候不合适……如果你从游戏开发开始,你会对这些东西有一个不平衡的看法,IMO。您还可能尝试对您真正不需要的区域进行微优化 - 但如果您在 C# 和 .NET 方面有扎实的基础,那么您将能够更好地了解所有内容。
关于c# - 为什么 C# 中的大多数类型都继承自 System.Object?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6476155/