0

0

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

黄舟

黄舟

发布时间:2017-02-11 13:25:40

|

1328人浏览过

|

来源于php中文网

原创

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位有效数字)

MagicLight AI
MagicLight AI

AI动画视频创作平台

下载
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();
        }

结果

再看引用类型定义的:

 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) 值类型,引用类型的内容,更多相关内容请关注PHP中文网(www.php.cn)!

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

32

2026.01.31

go语言 math包
go语言 math包

本专题整合了go语言math包相关内容,阅读专题下面的文章了解更多详细内容。

23

2026.01.31

go语言输入函数
go语言输入函数

本专题整合了go语言输入相关教程内容,阅读专题下面的文章了解更多详细内容。

16

2026.01.31

golang 循环遍历
golang 循环遍历

本专题整合了golang循环遍历相关教程,阅读专题下面的文章了解更多详细内容。

5

2026.01.31

Golang人工智能合集
Golang人工智能合集

本专题整合了Golang人工智能相关内容,阅读专题下面的文章了解更多详细内容。

6

2026.01.31

2026赚钱平台入口大全
2026赚钱平台入口大全

2026年最新赚钱平台入口汇总,涵盖任务众包、内容创作、电商运营、技能变现等多类正规渠道,助你轻松开启副业增收之路。阅读专题下面的文章了解更多详细内容。

268

2026.01.31

高干文在线阅读网站大全
高干文在线阅读网站大全

汇集热门1v1高干文免费阅读资源,涵盖都市言情、京味大院、军旅高干等经典题材,情节紧凑、人物鲜明。阅读专题下面的文章了解更多详细内容。

195

2026.01.31

无需付费的漫画app大全
无需付费的漫画app大全

想找真正免费又无套路的漫画App?本合集精选多款永久免费、资源丰富、无广告干扰的优质漫画应用,涵盖国漫、日漫、韩漫及经典老番,满足各类阅读需求。阅读专题下面的文章了解更多详细内容。

170

2026.01.31

漫画免费在线观看地址大全
漫画免费在线观看地址大全

想找免费又资源丰富的漫画网站?本合集精选2025-2026年热门平台,涵盖国漫、日漫、韩漫等多类型作品,支持高清流畅阅读与离线缓存。阅读专题下面的文章了解更多详细内容。

85

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 8.2万人学习

C 教程
C 教程

共75课时 | 4.4万人学习

C++教程
C++教程

共115课时 | 15.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号