热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C#基础知识整理:基础知识(11)值类型,引用类型

C#是面向对象的语言,在面向对象的思想中,只有对象,所有事物都可以用类描述。所以比如这些,int,bool,char,string,double,long等都是类,那么像

C#是面向对象的语言,在面向对象的思想中,只有对象,所有事物都可以用类描述。所以比如这些,int,bool,char,string,double,long等都是类,那么像,30,2.5,"test"都是对应类的一个对象。

        static void Main(string[] args)          {              string istring = 30.ToString();                string dstring = 2.5.ToString();                string sstring = "test".ToString();                Console.WriteLine(string.Format("{0},{1},{2}", istring, dstring, sstring));                Console.ReadLine();          }

输出:
C#基础知识整理:基础知识(11) 值类型,引用类型

 可以看出它们有ToString()这个方法,所以它们是对象。
 在平时写代码时,定义数据类型除了上述的这种之外,肯定都用过:

         static void Main(string[] args)          {              Int32 i = 0;                UInt32 j = 0;                String str = "test";                Console.ReadLine();          }

    这个其实是.NET的一个机制,.NET是一个平台,这个平台上有C#,VB这些语言。因此,.NET定义了一系列类型,映射到不同的语言中,Int32在c#中就是int。这样的数据类型称作基元类型,在C#中类的对象必须使用new生成。而这一部分类直接就可以用常量表示。基元类型定义在.net Framework中,System命名空间下。看一下基元类型在C#语言中的类型映射。

.NET Framework基元类型

C#类型

取值范围 备注

System.Boolean

bool

true/false /
System.Byte byte 0 ~255

无符号8位整数

System.Sbyte sbyte -128 ~ 127 有符号8位整数
System.Char char 0 ~ 65,535 无符号16位整数
System.Int16 short

-32,768 ~ 32,767

有符号16位整数
System.UInt16 ushort 0 ~ 65,535 无符号16位整数
System.Int32 int -2,147,483,648 ~ 2,147,483,647 有符号32位整数
System.Int64 long

-9,223,372,036,854,775,808 ~

9,223,372,036,854,775,807

有符号64位整数
System.UInt64 ulong

0 ~ 18,446,744,073,709,551,615

无符号64位整数
System.Single float

±1.5 × 10-45 ~ ±3.4 × 1038

(7位有效数字)

32位单精度浮点数
System.Double double

±5.0 × 10-324 到 ±1.7 × 10308

(15至16位有效数字)

64位双精度浮点
System.Decimal decimal

±1.0 × 10-28 到 ±7.9 × 1028

(27至28位有效数字)

128位浮点数数
System.String string 任意字符串 /
System.UInt32 uint 0 ~ 4,294,967,295 无符号32位整数

表中的除了string是引用类型(后面单独解释),其它都是值类型。
下面简单介绍下引用类型和值类型。
学习C语言的时候有个堆和栈的概念。
堆区——程序员分配释放,或者程序结束有OS回收,分配方式类似于链表。
栈区——由编译器自动分配释放,存放函数的参数值,变量值等。
栈内存结构可以快速的分配内存和回收内存,但栈空间有限,过多使用会“溢出”,因此栈只分配常用的,占用空间小的数据类型;堆内存结构分配内存较慢,但是利用空间大,可以存放大型数据。
在C#中,基本上所有的数据都存储在“堆”结构中,称之为“托管堆”,受.NET垃圾回收监控。但是相对于栈堆结构中内存分配效率比较低。为了正确进行垃圾回收,每次分配的堆空间比实际所需空间稍大,小型数据使用堆是不太合适的。
可以比较看一下值类型和引用类型:
C#中提供了Struct定义值类型,直接在栈上分配内存。

 ///       /// 使用struct定义一个值类型,      /// 值类型的只能实现接口,不能继承类      ///       public struct StructPositiveNumber : ICloneable        {          ///           /// 值类型字段          ///           private int number;            ///           /// 静态只读字段,作为类的初始值          ///           public readonly static StructPositiveNumber InitialValue = new StructPositiveNumber();            ///           /// 属性          ///           public int Number          {              get              {                  return number;              }                set              {                  if (value <= 0)                  {                      throw new Exception();                  }                    this.number = value;              }          }          ///           /// 可以定义构造器,但是和类不同,这里的默认构造器依然存在          ///           public StructPositiveNumber(int value)          {              if (value <= 0)              {                  throw new Exception();              }                this.number = value;          }            ///           /// 实现克隆方法,返回当前对象          ///           ///           public object Clone()          {              return new StructPositiveNumber(this.number);          }      }

调用

       static void Main(string[] args)          {              //声明变量,赋值              StructPositiveNumber pNumber1 = StructPositiveNumber.InitialValue;                pNumber1.Number = 1;                //pNumber1赋给pNumber2              StructPositiveNumber pNumber2 = pNumber1;                //改变pNumber2的值              pNumber2.Number = 2;                //看打印结果,改变了pNumber2的值,但是不影响pNumber1              Console.WriteLine(pNumber1.Number);//1                Console.WriteLine(pNumber2.Number);//2                //重新初始化pNumber2,通过构造器生成改变了初始值。              pNumber2 = new StructPositiveNumber(3);                Console.WriteLine(pNumber2.Number);//3                //调用Clone将pNumber2复制给pNumber1              pNumber1 = (StructPositiveNumber)pNumber2.Clone();                Console.WriteLine(pNumber1.Number);//3                //改变pNumber1的值,但是pNumber2值不改变              pNumber1.Number = 4;                Console.WriteLine(pNumber1.Number);//4                Console.WriteLine(pNumber2.Number);//3                Console.ReadLine();          }

结果
C#基础知识整理:基础知识(11) 值类型,引用类型

再看引用类型定义的:

 public class ClassPositiveNumber : ICloneable      {          private int number;            public int Number          {              get              {                  return this.number;              }                set              {                  if (value <= 0)                  {                      throw new Exception();                  }                    this.number = value;              }          }            //引用类型自己可以初始化为null,无需定义初始值          //public readonly static ClassPositiveNumber InitialValue = new ClassPositiveNumber();            public ClassPositiveNumber(int value)          {              if (value <= 0)              {                  throw new Exception();              }                this.number = value;          }            public object Clone()          {              return new ClassPositiveNumber(this.number);          }      }

调用

      static void Main(string[] args)          {              ClassPositiveNumber cNumber1;//默认值为null                cNumber1 = new ClassPositiveNumber(1);                ClassPositiveNumber cNumber2 = cNumber1;                cNumber2.Number = 2;                //可以看出,两个引用引用到了相同的对象              Console.WriteLine(cNumber1.Number);//2                Console.WriteLine(cNumber2.Number);//2                //重新初始化cNumber2,之前的对象已被丢弃              cNumber2 = new ClassPositiveNumber(3);                Console.WriteLine(cNumber2.Number);//3                            //复制是复制一个对象的副本,因此,是两个不同的对象              cNumber1 = (ClassPositiveNumber)cNumber2.Clone();                Console.WriteLine(cNumber1.Number);//3                cNumber1.Number = 4;                Console.WriteLine(cNumber1.Number);//4                Console.WriteLine(cNumber2.Number);//3                Console.ReadLine();          }

结果
C#基础知识整理:基础知识(11) 值类型,引用类型

通过例子,可以看出&#20540;类型的特点如下:
a、使用struct声明;
b、不能继承类,但是可以实现接口(当然除object类外);
c、&#20540;类型使用&#20540;类型做为字段,但是字段无法有默认&#20540;;
c、&#20540;类型中必须有默认构造器,而且自己定义构造器后,默认的无参数的构造器依然存在。而且在构造其中只能访问类中的字段,但是不能访问属性。符号=对于&#20540;类型来说是赋&#20540;,所以赋&#20540;是&#20540;类型变量不能为空,因为&#20540;类型没有引用的概念,肯定有&#20540;。

代码下载:http://download.csdn.net/detail/yysyangyangyangshan/4452051


推荐阅读
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • Java SE从入门到放弃(三)的逻辑运算符详解
    本文详细介绍了Java SE中的逻辑运算符,包括逻辑运算符的操作和运算结果,以及与运算符的不同之处。通过代码演示,展示了逻辑运算符的使用方法和注意事项。文章以Java SE从入门到放弃(三)为背景,对逻辑运算符进行了深入的解析。 ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • This article discusses the efficiency of using char str[] and char *str and whether there is any reason to prefer one over the other. It explains the difference between the two and provides an example to illustrate their usage. ... [详细]
  • 本文讨论了编写可保护的代码的重要性,包括提高代码的可读性、可调试性和直观性。同时介绍了优化代码的方法,如代码格式化、解释函数和提炼函数等。还提到了一些常见的坏代码味道,如不规范的命名、重复代码、过长的函数和参数列表等。最后,介绍了如何处理数据泥团和进行函数重构,以提高代码质量和可维护性。 ... [详细]
  • 本文详细介绍了使用C#实现Word模版打印的方案。包括添加COM引用、新建Word操作类、开启Word进程、加载模版文件等步骤。通过该方案可以实现C#对Word文档的打印功能。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 本文介绍了在Windows系统上使用C语言命令行参数启动程序并传递参数的方法,包括接收参数程序的代码和bat文件的编写方法,同时给出了程序运行的结果。 ... [详细]
  • 本文介绍了使用Python解析C语言结构体的方法,包括定义基本类型和结构体类型的字典,并提供了一个示例代码,展示了如何解析C语言结构体。 ... [详细]
  • C语言常量与变量的深入理解及其影响
    本文深入讲解了C语言中常量与变量的概念及其深入实质,强调了对常量和变量的理解对于学习指针等后续内容的重要性。详细介绍了常量的分类和特点,以及变量的定义和分类。同时指出了常量和变量在程序中的作用及其对内存空间的影响,类似于const关键字的只读属性。此外,还提及了常量和变量在实际应用中可能出现的问题,如段错误和野指针。 ... [详细]
author-avatar
平凡简单
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有