Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果System.Enum是一个类,它怎么可能也是一个ValueType?_C# - Fatal编程技术网

C# 如果System.Enum是一个类,它怎么可能也是一个ValueType?

C# 如果System.Enum是一个类,它怎么可能也是一个ValueType?,c#,C#,System.ValueType是一个类,从它派生的所有内容都是值类型,因此不能是类,因为类是引用类型 那么,继承System.ValueType的System.Enum怎么可能被定义为类呢?请参见: 虽然ValueType是值类型的隐式基类,但是 无法创建直接从ValueType继承的类。相反 个别编译器提供一个语言关键字或构造,例如 C中的struct和Structure…在Visual Basic中结束结构以支持 创建值类型 针对您的问题: 所以说所有类都是引用类型是错误的吗 您声明的任何

System.ValueType是一个类,从它派生的所有内容都是值类型,因此不能是类,因为类是引用类型

那么,继承System.ValueType的System.Enum怎么可能被定义为类呢?

请参见:

虽然ValueType是值类型的隐式基类,但是 无法创建直接从ValueType继承的类。相反 个别编译器提供一个语言关键字或构造,例如 C中的struct和Structure…在Visual Basic中结束结构以支持 创建值类型

针对您的问题:


所以说所有类都是引用类型是错误的吗

您声明的任何类都将是引用类型。因此,我认为将所有类都视为引用类型是正确的。不可能创建声明为类的值类型。您必须使用struct关键字。如果尝试模拟在枚举类中看到的内容:

  public class Test: ValueType
  {
      public string Text { get; set; }
  }
…您将得到错误“Test”无法从特殊类“System.ValueType”派生。我不知道是什么魔力使ValueType类变得特别,但据我所知,所有.NET语言都要求您使用特殊的关键字(如struct)来定义自己的值类型。它令人困惑,但可能有重要的用途,例如优雅地处理装箱/拆箱、reflection.IsValueType?以及类似的事情

如果你有一个抽象类,你不能实例化它,所以它会 永远不要进入堆,即不会像引用类型那样工作

是的,但这与ValueTypes完全不同。您可以声明像int这样的ValueType,为其赋值,传递它,可以将其解除绑定和装箱。这些都不能单独用于抽象类

顾名思义,它是其他一些具体类的抽象。当您声明SomeAbstractClass类型的变量时,除非您初始化它对继承该抽象类的某个具体类的引用,否则无法对其执行任何操作。因此,与该变量的每个操作/交互都将针对具体类进行,尽管它可能会利用抽象类中的一些实现。因此,无论何时使用抽象类变量,实际上都是在使用具体类,因此它仍然是引用类型,所有类似heap的内容都适用于它,就像任何其他引用类型一样。

请参见:

虽然ValueType是值类型的隐式基类,但是 无法创建直接从ValueType继承的类。相反 个别编译器提供一个语言关键字或构造,例如 C中的struct和Structure…在Visual Basic中结束结构以支持 创建值类型

针对您的问题:


所以说所有类都是引用类型是错误的吗

您声明的任何类都将是引用类型。因此,我认为将所有类都视为引用类型是正确的。不可能创建声明为类的值类型。您必须使用struct关键字。如果尝试模拟在枚举类中看到的内容:

  public class Test: ValueType
  {
      public string Text { get; set; }
  }
…您将得到错误“Test”无法从特殊类“System.ValueType”派生。我不知道是什么魔力使ValueType类变得特别,但据我所知,所有.NET语言都要求您使用特殊的关键字(如struct)来定义自己的值类型。它令人困惑,但可能有重要的用途,例如优雅地处理装箱/拆箱、reflection.IsValueType?以及类似的事情

如果你有一个抽象类,你不能实例化它,所以它会 永远不要进入堆,即不会像引用类型那样工作

是的,但这与ValueTypes完全不同。您可以声明像int这样的ValueType,为其赋值,传递它,可以将其解除绑定和装箱。这些都不能单独用于抽象类


顾名思义,它是其他一些具体类的抽象。当您声明SomeAbstractClass类型的变量时,除非您初始化它对继承该抽象类的某个具体类的引用,否则无法对其执行任何操作。因此,与该变量的每个操作/交互都将针对具体类进行,尽管它可能会利用抽象类中的一些实现。因此,无论何时使用抽象类变量,实际上都是在使用具体类,因此它仍然是引用类型,并且像heap这样的所有内容都适用于它,就像任何其他引用类型一样。

NET中的所有内容都源于System.Object:

引用和值类型都派生自最终基类对象。在需要使值类型的行为类似于对象的情况下,将使用ALLOCATE包装器使值类型看起来类似于引用对象 值类型的值被复制到堆中。包装器被标记,以便系统知道它包含值类型。这个过程称为装箱,而相反的过程称为拆箱。装箱和取消装箱允许将任何类型视为对象


.NET中的所有内容都源自System.Object:

引用和值类型都派生自最终基类对象。在需要使值类型的行为类似于对象的情况下,会在堆上分配一个使值类型看起来类似于引用对象的包装器,并将值类型的值复制到其中。包装器被标记,以便系统知道它包含值类型。这个过程称为装箱,而相反的过程称为拆箱。装箱和取消装箱允许将任何类型视为对象


因为编写C的人制定了规则:我认为System.Enum必须定义为类才能继承。有关更多信息,请参阅。我知道这并不能回答你的问题,但它似乎是相关的。@David:事实上,没有。。。写.NET的人制定了这条规则。C是许多用具体语言实现这些规则的编译器之一。@EricJ。你赢了。我只是开玩笑,但你是对的所以说:从System.ValueType派生的所有内容都是值类型,除了System.Enum是引用类型,因为它被定义为类?因为编写C的人制定了规则:我认为System.Enum必须定义为类才能继承。有关更多信息,请参阅。我知道这并不能回答你的问题,但它似乎是相关的。@David:事实上,没有。。。写.NET的人制定了这条规则。C是许多用具体语言实现这些规则的编译器之一。@EricJ。你赢了。我只是开玩笑,但你是对的所以说:从System.ValueType派生的所有内容都是值类型,除了System.Enum是引用类型,因为它被定义为类?所以说所有类都是引用类型是错误的吗?如果你有一个抽象类,你不能实例化它,所以它永远不会出现在堆上,也就是说,不会像引用类型那样工作?那么说所有的类都是引用类型是错误的吗?如果你有一个抽象类,你不能实例化它,所以它永远不会出现在堆上,也就是说,它不会像引用类型那样工作?一个潜在的混淆点是,int和Int32是一样的,int只是Int32的一个C别名。我过去认为int是值类型,Int32是装箱类,但事实并非如此。ECMA规范将每个值类型定义视为定义存储位置类型和包装器对象类型。包装器对象的行为类似于System.object的派生,因为它是一个对象,并且表现出引用语义;存储位置类型不支持这两种类型。认为一切都是对象的派生的想法是一个漏洞百出、毫无帮助的抽象。一个潜在的混淆点是,int和Int32是同一件事,int只是Int32的一个C别名。我过去认为int是值类型,Int32是装箱类,但事实并非如此。ECMA规范将每个值类型定义视为定义存储位置类型和包装器对象类型。包装器对象的行为类似于System.object的派生,因为它是一个对象,并且表现出引用语义;存储位置类型不支持这两种类型。认为一切都是对象的派生的想法是一种漏洞百出、毫无帮助的抽象。