【问题标题】:Why does every class in .NET inherit from Object?为什么 .NET 中的每个类都继承自 Object?
【发布时间】:2009-10-17 23:23:49
【问题描述】:

没看懂……

为什么他们需要一个共同的基地?

【问题讨论】:

    标签: c# object


    【解决方案1】:

    这个问题以虚假为前提。它们不需要通用的基本类型。这一选择并非出于必要。它是出于为客户提供最佳价值的愿望。

    在设计类型系统或其他任何事情时,有时您会遇到决策点——您必须决定是 X 还是非 X。通用基础类型或无通用基础类型。发生这种情况时,您权衡 X 的成本和收益以确定净值,然后权衡非 X 的成本和收益以确定净值,然后选择价值更高的那个。拥有共同基类型的收益大于成本,由此产生的净收益大于没有共同基类型的净收益。所以我们选择有一个通用的基类型。

    这是一个相当模糊的答案。如果您想要更具体的答案,请尝试提出更具体的问题。

    【讨论】:

    • “为客户带来最佳价值”是我认为的实际思考方式。优雅和结构良好的设计似乎是另一个。事实上,无论您以何种方式考虑事物,都存在一种平衡。
    • 像个做标记的人一样说话。您想为 X 和非 X 添加一些优点和缺点吗?您如何衡量拥有或没有通用基类的价值?
    • 优雅和结构良好的设计通常既实用又对客户有益;事实上,它们通常表明我们已经找到了正确的解决方案。不总是,但通常。
    • 营销就是创造对产品和服务的需求;我没有尝试这样做。我是以设计者和实施者的身份发言;我不确定你认为这听起来像营销是什么。如果您想要详细分析类型系统设计各个方面的优缺点,我建议这不是适合这种长度的工作的论坛。
    【解决方案2】:

    我认为,主要是为了有一个类型来引用任何对象。 object 类型的参数可以是原始类型、结构、引用类型,等等。拥有这样的类型很重要。

    然后是每个类型都实现了一些通用成员,例如 Equals、ToString、GetHashCode。这确实也可以是一个通用接口,但是您不会继承默认实现。

    【讨论】:

    • 重要,例如,对于像 HttpContext.Items 这样的异构集合,您希望能够将 anything 放入其中。
    • 真的,该示例扩展为 any 示例(例如,我想要一个方法采用 any 类型的参数)。这只是对类型系统中的所有类型有一些共同期望的好处之一。
    • 另一个例子可以是 BinaryFormatter.Serialize(Stream, Object)
    【解决方案3】:

    因为它在spec:

    8.9.9 对象类型继承
    随着 System.Object 的唯一例外,它 不从任何其他对象继承 类型,所有对象类型应要么 显式或隐式声明 支持(即继承自) 恰好是另一种对象类型。这 继承关系图应 形成一棵单根树 System.Object 位于基础;即,所有 对象类型最终继承自 System.Object 类型。

    这种设计方法有几个benefits

    【讨论】:

    • “它在规范中”并没有对设计推理产生太多影响,我认为这就是 Tom 试图理解的:它只是引出了一个问题,“那么为什么规范这么说?”
    • 我是个聪明人。要回答“为什么它在规范中”,请参阅 Eric 的回复 (stackoverflow.com/questions/1583482/…)。
    【解决方案4】:

    许多/大多数是的一些原因:

    提供Equals、Finalize、GetHashCode、ToString等常用成员......

    帮助拳击......

    【讨论】:

    • 不错的尝试,但没有雪茄。问题是“为什么每个类都派生自对象”,是的,每个类都派生自对象。
    • 删除了我指向您帖子的链接。 :-)
    【解决方案5】:

    Java 和 C# 对此采取了不同的方法。这主要与性能有关。

    如果你想象每个对象都可以为空,那么它必须是一个指向值的指针,可以将其更改为指向空的指针。现在这意味着对于每个对象,您至少需要一个指针和一块内存来存储值。

    Java 有原始值的概念,它不是对象。它没有指针,也不能为空。这打破了 OOP 范式,但在性能方面是有意义的。

    C#(或更准确地说是 CLR + BCL)尝试了一个很好的折衷方案,即 ReferenceType 和 ValueType 派生。任何从 ValueType 派生的东西都被视为 CLR 的原语,避免了对象引用。然而,这个值仍然可以通过装箱被视为对象,允许您获得原始类型的性能优势,但允许将所有内容都视为对象。

    这些东西之间真正的关键区别在于将参数传递给方法的语义。如果一切都是对象,那么您将传递对对象的引用,即可以通过将对象传递给方法来更改对象。基元和 C# 值类型是按值传递的,因此它们被有效地复制到方法调用中,并且原始值不变。

    这是标准的开发故事。先试着把它做好,然后看看你是否可以在看到瓶颈后对其进行优化。传递值语义还允许您防止编码错误的可变性。 (例如,在 C# 中传递一个类与一个结构)

    【讨论】:

      【解决方案6】:

      到字符串。例如。

      【讨论】:

      • 为什么有人反对这个?可以肯定的是,这不是最彻底的答案,但它是对象即公共基础方法的好处的一个很好的例子。 +1
      【解决方案7】:

      对装箱和拆箱很有用

      reference

      【讨论】:

        【解决方案8】:

        .NET 中的每个对象都有共同的属性和方法。但是,这些又分为两类:值类型和引用类型。值类型(即 int)存储在堆栈中,引用类型(即您的自定义类)存储在堆中。引用类型存储对实际数据的引用(即在堆上)。值类型直接包含它们的数据。

        您可以在 MSDN 上阅读更多内容:

        http://msdn.microsoft.com/en-us/library/system.object.aspx

        【讨论】:

          【解决方案9】:

          作为其他“答案”的旁注,结构是一种值类型,它也继承自对象。

          也许答案是它假设我们正在编程面向对象的风格/范式?球是一个物体。剑是物体。员工是一个对象。采购订单是一个对象。

          一些公司将他们的 .NET(或 Java、Ruby 或 PHP)应用程序设计为继承自一个公共基类,以便在他们的系统中以同样的方式对待它们。如果我在过去的 Java 时代没记错的话……所有 EJB 共享同一个基类,以便统一管理和识别它们。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-03-30
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多