千家信息网

C#基元类型、值类型、引用类型是什么

发表于:2024-11-25 作者:千家信息网编辑
千家信息网最后更新 2024年11月25日,这篇文章主要讲解了"C#基元类型、值类型、引用类型是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"C#基元类型、值类型、引用类型是什么"吧!首先了
千家信息网最后更新 2024年11月25日C#基元类型、值类型、引用类型是什么

这篇文章主要讲解了"C#基元类型、值类型、引用类型是什么",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"C#基元类型、值类型、引用类型是什么"吧!

首先了解下什么是基元类型,基元类型是编译器直接支持的数据类型,像我们平时经常用到的int string bool 都是基元类型,基元类型是映射到FCL中的类型,像前面的三种类型对应到FCL中就是Int32 String Boolean,基元类型只是给我们的编程提供了方便,它和FCL中的类型在编译后最终生成的IL完全相同。下面给出基元类型和FCL类型的对应表
我们平时在写程序时通常都是使用基元类型,因为方便,但本书的作者认为应该直接使用FCL中的类型,原因如下:

C#基元类型

FCL类型

CLS相容

说明

sbyte

System.Sbyte

byte

System.Byte

short

System.Int16

ushort

System.UInt16

int

System.Int32

uint

System.Uint32

long

System.Int64

ulong

System.Uint64

char

System.Char

float

System.Single

double

System.Double

bool

System.Boolean

decimal

System.Decimal

object

System.Object

string

System.String

在c#中long对应的FCL类型为System.Int64,但是在其他的语言中,如c++ 就将long视为一个Int32。这样习惯于一种编程语言的人在看另一种编程语言写的源码是就会产生错误的理解。在FCL中的许多的方法将类型名作为方法名的一部分,如System.Convert类提供ToBoolean,ToInt32,ToSingle等。这样在使用基元类型做类型转换时就感觉有点怪怪的,如:float val=Convert.ToSingle("23");

CLR VIA C#教程之值类型和引用类型的区别
1.所有的值类型都是从System.TypeValue派生,如Struct Enum都是值类型;所有引用类型都是从System.Object派生。
2.值类型分配在线程堆栈上,引用类型分配在托管堆上。
3.值类型表现形式有未装箱形式和已装箱形式,而引用类型总是已装箱形式。
4.所有的值类型都是sealed类型,所以值类型不能作为任何类型的基类型,也不能在值类型中引入虚方法。
5.创建一个引用类型变量时,会被初始化为null,试图使用一个null的引用类型变量时,会抛出NullReferenceException异常,也就是常见的"未将对象引用设置到对象的实例";值类型在创建时所有成员都初始化为0了,所以不会抛出该异常。

原文例子表示值类型和引用类型的区别

class Program  {  static void Main(string[] args)  {  SomeRef r1 = new SomeRef();  SomeVal v1 = new SomeVal();  r1.x = 5;  v1.x = 5;  Console.WriteLine(r1.x);    //5  Console.WriteLine(v1.x);    //5  SomeRef r2 = r1;  SomeVal v2 = v1;  r1.x = 8;  v1.x = 9;  Console.WriteLine(r1.x);    //8  Console.WriteLine(r2.x);    //9  Console.WriteLine(v1.x);    //9  Console.WriteLine(v2.x);    //5  }  }  class SomeRef  {  public Int32 x;  }  struct SomeVal  {  public Int32 x;  }


CLR VIA C#教程之CLR中类型字段布局的控制

为了提高性能,clr能按照所选择的任何方式来排列类型的字段。我们可以通过在类会是结构上使用System.Runtime.InteropServices.StructLayoutAttribute属性来改变这种排列的顺序。该属性接受一个LayoutKind的枚举值(Auto,Sequential,Explicit),默认情况下C#编译器会为类选择Atuo,为结构选择Sequential。下面来定义一个类和一个结构

struct SomeVal  {  public String name;  public Int32 id;   }   class SomeRel  {  public String name;  public Int32 id;  }

查看IL代码可以看到默认的排列顺序

现在给类和结构加上属性,首引用加命名空间 using System.Runtime.InteropServices;

[StructLayout(LayoutKind.Auto)]  struct SomeVal  {  public String name;  public Int32 id;  }  [StructLayout(LayoutKind.Sequential)]  class SomeRel  {  public String name;  public Int32 id;  }

再查看IL可以看到顺序已经发生了变化

C#编译器总是会默认给结构这样的值类型选择Sequential,是因为值类型会经常和非托管代码进行交互,字段必须保持和开发人员定义的一致。我们在编码过程中如果判断所创建的值类型不会与非托管代码进行交互,就可以像上面那样给创建的值类型添加[StructLayout(LayoutKind.Auto)] ,让其进行自动排列,以提高性能。

感谢各位的阅读,以上就是"C#基元类型、值类型、引用类型是什么"的内容了,经过本文的学习后,相信大家对C#基元类型、值类型、引用类型是什么这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

0