C# 如果我的类没有';你没有继承任何东西吗?

C# 如果我的类没有';你没有继承任何东西吗?,c#,.net,oop,inheritance,C#,.net,Oop,Inheritance,我有点搞不清楚下面的代码是如何工作的 public class DefaultClass { public override bool Equals(object obj) { return base.Equals(obj); } } 我的问题是:我没有继承任何类,但我如何仍然能够重写Equals方法。此代码在VS2010中得到完美编译。你知道这是怎么回事吗?因为你的DefaultClass默认情况下“继承”自 您现在正在覆盖 不过我理解这种困惑。表示这

我有点搞不清楚下面的代码是如何工作的

public class DefaultClass
{
    public override bool Equals(object obj)
    {
        return base.Equals(obj);
    }
}

我的问题是:我没有继承任何类,但我如何仍然能够重写Equals方法。此代码在VS2010中得到完美编译。你知道这是怎么回事吗?

因为你的
DefaultClass
默认情况下“继承”自

您现在正在覆盖

不过我理解这种困惑。表示这样的类不继承任何其他类,但它继承了(
object
):

继承:无。示例:
ClassA{}

是所有类的父类,所有类都从中继承。因此,您的
默认类
也继承了
对象

这是.NET Framework中所有类的最终基类; 它是类型层次结构的根

您可以使用树结构来理解这一点:

                     System.Object
                     /           \
                    /             \
                   /               \
SomeProject.DefaultClass        SomeProject.SomeOtherBaseClass
                                         /           \
                                        /             \
                                       /               \
                   SomeProject.ChildClass1       SomeProject.ChildClass2

另一方面,请务必查看Eric Lippert撰写的这篇非常相关的文章,这篇文章可能有助于您理解对象类:-

您的默认类继承自类。这是.NET Framework中所有类的最终基类;它是类型层次结构的根

这就是为什么可以重写它的方法

因为.NET Framework中的所有类都是从Object派生的,所以在Object类中定义的每个方法在系统中的所有对象中都是可用的。派生类可以并且确实重写其中一些方法,包括:

  • Equals
    -支持对象之间的比较
  • Finalize
    -在自动回收对象之前执行清理操作
  • GetHashCode
    -生成与对象值对应的数字,以支持使用哈希表
  • ToString
    -生成一个人类可读的文本字符串,用于描述类的实例

对象类是所有用户定义类的基类,因为您创建了一个名为DefaultClass的类,这将按对象类的子类进行设置。因此,Equals()方法已在对象类中定义,因此您将在此处重写此方法。

System.Object是.NET Framework中所有类的最终基类;它是类型层次结构的根

因此,所有类都可以重写该类中定义的方法。
在System.Object类中定义的方法有Equals()、Finalize()、GetHashCode()和ToString()

您认为您不是从任何类继承的理解是不正确的

见:

因为类是中所有类型的基类 .NET Framework
对象.Equals(对象)
方法提供 所有其他类型的默认相等比较。但是,类型 通常覆盖Equals方法来实现值相等


但是,请记住阅读:

“如果我的类没有从任何对象继承?”您走错了方向,因为()每个类都继承自
对象
@TimSchmelter:Close——每个类都继承自
对象
。像接口和指针这样的东西不会继承,因为它们不是类。@Gabe:是的,用类型替换类是正确的。但不仅类派生自对象,还派生值类型,如
struct
enum
@TimSchmelter:value类型是一种奇怪的情况;根据ECMA规范,每个
类型
都有效地定义了两种类型:一种是存储位置类型,另一种是堆对象类型。存储位置类型可以实现接口以及方法
Boolean Equals(Object)
Int32 HashCode()
、和
String ToString()
,但因为它们既不包含封装也不引用
对象的内部数据结构,所以它们实际上并不从中“继承”。@supercat:。除此之外,你在那里失去了我。例如,一个int的类型是System.Int32,它覆盖了对象中的几个方法,如ToString或GetHashCode。为了清楚起见,C#中的所有类型都继承自父类对象,这就是为什么您可以引用对象的任何ref或value的所有实例。@Liran根据ECMA规范,除了从
ValueType
派生的
Enum
之外,每个
Type
有效地定义了存储位置类型和堆对象类型。堆对象类型派生自
对象
,存储位置类型可转换为
对象
,但在ECMA规范的术语中,存储位置类型不继承自对象[这意味着,如果X从Y继承,X类型的值或对X类型对象的引用必须可以直接用作Y类型的值,而无需任何表示形式的转换]。@ScottChamberlain-Eric Lippert给出的示例主要是指针或“模板”类型,这两种类型都是可以理解的;首先,指针在C#中公开,特别是为了使C#代码能够与非托管代码以编组之类的方式进行互操作。它们在“日常”中也非常不受欢迎C#代码。普通C#代码编写者更感兴趣的是接口和开放泛型,它们基本上都是“模板”;它们本身是不可实例化的,因此也不是对象,但它们定义了从对象派生的实例的结构规则。@ScottChamberlain:IMHO,混淆主要是因为使用了“类型”之类的词描述几个不同的相似但不同的概念。给定
var l=new List{1,2,3};var e1=l.GetEnumerator();IEnumerator e2=e1;
,则
typeof(e1)
e2.GetType()
都将产生
List.Enumerator
,但在语义上