您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息
免费发信息
三六零分类信息网 > 延安分类信息网,免费分类信息发布

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

2024/3/22 7:42:36发布15次查看
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(); }
输出:
可以看出它们有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定义值类型,直接在栈上分配内存。
/// <summary> /// 使用struct定义一个值类型, /// 值类型的只能实现接口,不能继承类 /// </summary> public struct structpositivenumber : icloneable { /// <summary> /// 值类型字段 /// </summary> private int number; /// <summary> /// 静态只读字段,作为类的初始值 /// </summary> public readonly static structpositivenumber initialvalue = new structpositivenumber(); /// <summary> /// 属性 /// </summary> public int number { get { return number; } set { if (value <= 0) { throw new exception(); } this.number = value; } } /// <summary> /// 可以定义构造器,但是和类不同,这里的默认构造器依然存在 /// </summary> public structpositivenumber(int value) { if (value <= 0) { throw new exception(); } this.number = value; } /// <summary> /// 实现克隆方法,返回当前对象 /// </summary> /// <returns></returns> 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(); }
结果
再看引用类型定义的:
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(); }
结果
通过例子,可以看出值类型的特点如下:
a、使用struct声明;
b、不能继承类,但是可以实现接口(当然除object类外);
c、值类型使用值类型做为字段,但是字段无法有默认值;
c、值类型中必须有默认构造器,而且自己定义构造器后,默认的无参数的构造器依然存在。而且在构造其中只能访问类中的字段,但是不能访问属性。符号=对于值类型来说是赋值,所以赋值是值类型变量不能为空,因为值类型没有引用的概念,肯定有值。
以上就是c#基础知识整理:基础知识(11) 值类型,引用类型的内容。
延安分类信息网,免费分类信息发布

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录