在.NET中,每种类型都继承自System.Object吗?

25 浏览
0 Comments

在.NET中,每种类型都继承自System.Object吗?

这可能是一个非常基本的问题,但是我有点困惑。\n如果我反思Int32/Double/任何值类型的代码,我会发现它们都是结构体,看起来像这样:\n

[Serializable, StructLayout(LayoutKind.Sequential), ComVisible(true)]
public struct Double : IComparable, IFormattable, IConvertible, IComparable, IEquatable
{
....
}

\n那么,为什么我们说.NET中的所有东西都派生自System.Object?我觉得我在这里漏掉了一些关键点。\n编辑:\n让我更困惑的是,一个值类型(结构体)如何继承自System.Object这个类。

0
0 Comments

在最近的一篇博文中,Eric Lippert谈到了这个问题:并非所有类型都继承自System.Object。这是一篇非常有价值的阅读。

在这篇博文中,Eric Lippert解释了为什么并非所有类型都继承自System.Object。他指出,.NET中的所有类型都可以选择是否继承自System.Object,而不是强制性地继承。这是因为C#和其他.NET语言提供了一种将结构类型(如int、float等)直接编译为机器码的方式,而不需要创建对象。这种方式可以提高性能,尤其是在处理大量数据时。

然而,Eric Lippert还指出,尽管某些类型不直接继承自System.Object,它们仍然具有一些公共方法和属性,这些方法和属性是从System.ValueType继承而来的。这些方法和属性包括ToString、Equals和GetHashCode等。

解决这个问题的方法很简单:当我们需要在不知道具体类型的情况下使用对象时,可以将该对象视为System.Object类型。因为所有类型都可以转换为System.Object类型,所以我们可以使用System.Object类型的方法和属性来操作这些对象。这种方式被称为“装箱”。

下面是一个示例代码,展示了如何将一个不继承自System.Object的类型转换为System.Object类型并使用其中的方法:

// 声明一个不继承自System.Object的类型

struct MyStruct

{

public int myField;

}

// 将MyStruct类型的对象转换为System.Object类型

MyStruct myStruct = new MyStruct();

object boxedObject = (object)myStruct;

// 使用System.Object类型的方法

Console.WriteLine(boxedObject.ToString());

在上面的示例中,我们声明了一个不继承自System.Object的结构类型MyStruct。然后,我们将一个MyStruct类型的对象转换为System.Object类型,并使用System.Object类型的ToString方法打印出对象的字符串表示。

总之,尽管并非所有类型都继承自System.Object,但我们仍然可以将这些类型视为System.Object类型,并使用其中的方法和属性。这种方式使得我们能够在不知道具体类型的情况下操作对象。

0
0 Comments

在.NET中,不是每个类型都继承自System.Object,但System.Double是继承自System.Object的。

为什么会出现这个问题?根据Eric Lippert的帖子,所有值类型(包括枚举和可空类型)都派生自object。在C#中,结构体(struct)是System.ValueType的语法糖,这意味着System.Double派生自System.ValueType。由于System.ValueType派生自System.Object,所以System.Double也派生自System.Object。

你可以通过查看.NET Framework源代码或使用.NET Reflector来验证这一点。在.NET Framework源代码或.NET Reflector中可以看到以下代码:

.class public sequential ansi serializable sealed beforefieldinit Double

extends System.ValueType

解决方法是,如果你选择C#作为代码查看工具栏的编程语言,你会看到Double派生自System.ValueType的信息。如果你选择IL作为编程语言,你会看到Double继承自System.ValueType的信息。这不仅适用于Double类型,还适用于int、short、long、decimal等所有基本类型,它们都继承自System.ValueType。

对于那些认为Double是一个结构体,不可能继承自System.ValueType的人来说,请阅读这个答案。如果你查看IL代码而不是元数据或反编译成C#代码,你会看到Double继承自ValueType。根据C#规范,结构体是值类型,所有结构体类型隐式地继承自System.ValueType。

0
0 Comments

在这篇文章中,提到了一个关于.NET类型是否都继承自System.Object的问题。文章中提到,所有的结构体(struct)都继承自System.ValueType,而System.ValueType又继承自System.Object。而枚举(enum)则继承自System.Enum,而System.Enum又继承自System.ValueType。

文章中提到,值类型(value type)从引用类型(reference type)派生并没有问题。继承是两个类型之间的“is-a”关系。然而,为了将值类型视为对象实例,它必须被装箱(boxed)。当你将一个值传递给一个期望对象参数的方法时(或者调用在System.Object中实现的实例方法时),这个装箱过程会隐式地发生。

在文章的后面,有读者提到在反编译工具中看不到枚举和结构体继承自System.ValueType的信息。另一个读者回答说可以使用.NET Reflector和ildasm.exe来查看这些信息。在.NET Reflector中,可以打开mscorlib -> System -> Int32, Enum, ... -> Base Types,就能看到System.ValueType。

最后,读者还提到自己看到了枚举,但在反编译工具中没有看到结构体。另一个读者回答说如果切换到IL视图就能看到结构体。

总之,根据这篇文章的内容,每个.NET类型都是一个类,所有的结构体和枚举都继承自System.Object的子类。

0