C# 数据类型详解以及变量、对象与内存
学习刘铁猛老师《C#语言入门详解》视频,针对其中重点知识点进行总结。
1、什么是类型?
类型又称为数据类型(Data Type),数据类型在数据结构中的定义是一个值的集合以及定义在这个值集上的一组操作。
可以简单理解为数据在内存中存储的“型号”;小内存容纳大尺寸数据会丢失精准度,发生错误;而大内存容纳小尺寸数据会导致浪费。
还应注意编成语言的数据类型与数学中的数据类型不完全相同,例如数学中 3/4=0.75 而在C# 语言中 3 /4 =0。
不同的编程语言对数据类型的约束程度不一样,所以有强类型编程语言和弱类型编程语言的区分。
变量是用来存储值得所在处,它们有名字和数据类型。变量的数据类型决定了如何将代表这些值的位存储到计算机的内存中。
我们都知道,计算机的世界是二进制的,仅仅用0和1就构建了所有的表达,计算机用来存储0或者1的单位就是位(bit),8个位组成一个字节(byte)。
2、数据类型在C#语言中的作用
一个C#类型中所包含的信息有:
- 存储此类型变量所需的内存空间大小 如 int 类型需要4个字节也就是4*8=32位进行存储
- 此类型的值可表示的最大、最小值范围 sbyte占一个字节8位,s前缀表示带符号位,取值范围-128到127,byte占一个字节,不带符号位,取值范围位0-255。
- 此类型所包含的成员(如方法、属性、事件等) 可以用于ide的错误识别和反射时动态调用
- 此类型由何基类派生而来
- 程序运行的时候,此类型的变量在分配在内存的什么位置(栈或堆)
- 此类型所允许的操作(运算)
3、程序的内存使用分析
- Stack简介:函数调用使用,函数调用实际可以理解位栈帧的入栈出栈操作。空间较小,一般1-2M
- Stack overflow 空间较小所以会出现栈空间溢出的情况。例如递归函数未正常结束。
- Heap简介:用来存储对象(实例)使用,空间较大,可以达到数G
- 使用Perfomance Monitor观察内存使用情况
- 关于内存泄漏 未使用的对象未赋值为null导致垃圾收集器未处理,导致空间浪费,这称为内存泄漏。
这里给出观察内存使用情况的一个样例,新增的wpf程序,使用Winform程序也是可行的。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes; namespace HeapSample
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
} List<Window> winList; private void Btn_Consume_Click(object sender, RoutedEventArgs e)
{
winList = new List<Window>();
for (int i = ; i < ; i++)
{
Window wd = new Window();
winList.Add(wd);
}
} private void Btn_ClearHeap_Click(object sender, RoutedEventArgs e)
{
winList.Clear();
}
}
}
至于Perfomance Monitor观察内存使用情况,可以查看 https:////www.cnblogs.com/FreeLoopPowter/p/12298482.html 。
4、C# 数据类型系统
C#的五大数据类型
- 类(class):如 Form,Window,Console.String
- 结构体(structres):如 Int32,Int64,SIngle,Double
- 枚举(Enumerations):如Visibility,WindoState
- 接口(Interfaces)
- 委托(Delegate)
C#类型的派生谱系

这里顺带提一点,我们经常在编辑器中使用结构体时,例如定义一个32位的整型变量时,我们基本使用 int a=5; 这样的形式,这并不是前面说的结构体类型包含的内容,为啥没有报错呢?
这是由于某些数据类型如此常用,以至于许多编辑器允许代码以简化语法来操纵它们(也叫关键字)。这种语法不仅增强了代码的可读性和书写的方便性,生成的IL代码还与使用对应的FCL类库中的类型一致。
这类编译器能直接支持的类型称为 基元类型。基元类型直接映射到Framework类库(FCL)中存在的类型,可以通过按 F12 查看定义,就可以看到映射的FCL类型。
查看CLR Via C#一书,发现其对值类型和引用类型的阐述非常明了,还包括了对值类型和引用类型内存分配的讲解。这里选取重要内容进行记录,方便自己后续温习。对数据类型的内存分配情况的分析有利于后续理解方法的传值参数、引用参数、输出参数的理解。
CLR支持两种类型:引用类型和值类型。虽然FCL的大多数类型都是引用类型,但程序员使用最多的还是值类型。引用类型总是从托管堆中分配,C#的new 操作符返回对象内存地址——即指向对象数据的内存地址。使用引用类型必须留意性能问题,首先认清楚以下四个事实。
- 内存必须从托管堆分配。
- 堆上分配的每个对象都有一些额外成员。
- 对象中的其他字段(为字段而设)总是设为零。
- 从托管堆分配对象时,可能强制执行一次垃圾回收。(当垃圾回收器发现内存不够时会强制执行一次垃圾回收)
如果所有类型都是引用类型,应用程序的性能将显著下降。设想每次使用 Int32 时都进行一次内存分配,性能会收到多么大的影响!为了提升简单和常用的数据类型的性能,CLR提供了名为“值类型”的轻量级类型。值类型的实例一般是在线程栈上分配(虽然也可作为字段嵌入引用类型的对象中),在代表值类型实例的变量中不包含指向实例的指针。变量中包含了实例本身的字段。由于变量已包含了实例的字段,所以操作实例中的字段不需要提取指针。值类型的实例不受垃圾回收器的控制。因此,值类型的使用缓解了托管堆的压力,并减少了应用程序生存期间的垃圾回收次数。
下面给出一个示例,结合图示讲解值类型和引用类型的区别。引用类型变量对对象实例的引用实际上是以在栈中分配的引用类型变量存放堆中实例的起始内存地址来实现的。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace RefTypeAndValueTypeApp
{
class Program
{
static void Main(string[] args)
{
//在堆上分配空间
SomeRef r1 = new SomeRef();
//在栈上分配空间
SomeValue v1 = new SomeValue();
r1.x = ;//提取指针,给指针引用的对象赋值
v1.x = ;//在栈上修改,由0修改为5
Console.WriteLine(r1.x);//显示 "5"
Console.WriteLine(v1.x);//同样显示 "5"
//以上内存分配情况见图左边 //只复制引用(指针)
SomeRef r2 = r1;
//在栈上分配并复制成员
SomeValue v2 = v1;
r1.x = ;//r1.x 和 r2.x 都会改变
v1.x = ;//v2.x会改变 v1.x不会改变
Console.WriteLine(r1.x);//显示 "8"
Console.WriteLine(r2.x);//同样显示 "8"
Console.WriteLine(v1.x);//显示 "9"
Console.WriteLine(v2.x);//显示 "5"
//以上部分程序执行的内存分配情况见图右侧 //让控制台等待输入,有输入后才终止
Console.ReadKey();
}
}
/// <summary>
/// 引用类型
/// </summary>
class SomeRef
{
public Int32 x;
} /// <summary>
/// 值类型
/// </summary>
struct SomeValue
{
public Int32 x;
}
}

书写这篇随笔的主要目的是自己温习和防遗忘,本着分享的心态公开,如有不妥之处,还请指出,相互交流。
C# 数据类型详解以及变量、对象与内存的更多相关文章
- Python之路-变量和基本数据类型详解(变量、数据类型、)
一.注释 注释的作用: 增加程序的可读性 作为调试用 提高团队的合作效率 注释的分类 1.单行注释 以井号(#)开头,右边的所有内容当做说明 2.多行注释 以三对单引号(’’’注释内容’’’)将注释包 ...
- 详解Go变量类型的内存布局
定义 每当我们编写任何程序时,我们都需要在内存中存储一些数据/信息.数据存储在特定地址的存储器中.内存地址看起来像0xAFFFF(这是内存地址的十六进制表示). 现在,要访问数据,我们需要知道存储它的 ...
- c# 把一个匿名对象赋值给一个Object类型的变量后,怎么取这个变量? c# dynamic动态类型和匿名类 详解C# 匿名对象(匿名类型)、var、动态类型 dynamic 深入浅析C#中的var和dynamic
比如有一个匿名对象,var result =......Select( a=>new { id=a.id, name=a.name});然后Object obj = result ;我怎 ...
- 2-2和2-3基本数据类型 & 2-4基本数据类型详解 & 3-1和3-2整形字面量值及变量声
2-4基本数据类型详解 3-1和3-2整形字面量值及变量声 023是八进制的 0x1357是十六进制 0X3C也是十六进制 0x1abL:长整型 变量声明 数据类型 空格 变量名 赋值: 变量的定义:
- python 数据类型详解
python数据类型详解 参考网址:http://www.cnblogs.com/linjiqin/p/3608541.html 目录1.字符串2.布尔类型3.整数4.浮点数5.数字6.列表7.元组8 ...
- python数据类型详解(全面)
python数据类型详解 目录1.字符串2.布尔类型3.整数4.浮点数5.数字6.列表7.元组8.字典9.日期 1.字符串1.1.如何在Python中使用字符串a.使用单引号(')用单引号括起来表示字 ...
- 转 python数据类型详解
python数据类型详解 目录 1.字符串 2.布尔类型 3.整数 4.浮点数 5.数字 6.列表 7.元组 8.字典 9.日期 1.字符串 1.1.如何在Python中使用字符串 a.使用单引号(' ...
- 详解js变量、作用域及内存
详解js变量.作用域及内存 来源:伯乐在线 作者:trigkit4 原文出处: trigkit4 基本类型值有:undefined,NUll,Boolean,Number和Strin ...
- python之数据类型详解
python之数据类型详解 二.列表list (可以存储多个值)(列表内数字不需要加引号) sort s1=[','!'] # s1.sort() # print(s1) -->['!', ' ...
随机推荐
- 异数OS TCP协议栈测试(二)--短连接篇
异数OS TCP协议栈测试(二)--短连接篇 本文来自异数OS社区 github: 异数OS-织梦师(消息中间件)群: 476260389 测试目标 TCP 短链接IO性能测试,Client Se ...
- 从0开发3D引擎(八):准备“搭建引擎雏形”
大家好,现在开始本系列的第三部分,按照以下几个步骤来搭建引擎雏形: 1.分析引擎的需求 2.实现最小的3D程序 3.从中提炼引擎原型 4.一步一步地对引擎进行改进,使其具备良好的架构 5.实现与架构相 ...
- Treap基本用法总结
Treap=Tree+Heap 起名的人非常有才 Treap是啥? 一棵二叉搜索树可能退化成链,那样各种操作的效率都比较低 于是可爱的Treap在每个节点原先值v的基础上加了一个随机数rnd,树的形 ...
- ubuntu文件操作mkdir cp mv rm ln
pwd:显示当前目录 date:显示当前日期 cal:显示日历 ls:列出目录内容 cd:改变当前工作目录 ‘.’:代表工作目录 ‘..’:代表工作目录父目录 进入当前目录的父目录:cd /home ...
- 【阿K学Python系列】一Python基础语法(二)
前言 通过上一章的学习[阿k学Python]一Python入门(一),我们已经初步了解到Python是一种解释型.面向对象.动态数据类型的高级程序设计语言,当然也是一门脚本语言,像前端需要学习的Jav ...
- java 编程小知识点
--------------------------------- 时间不多了,抓紧做自己喜欢的事情 1. 使用位运算 & 来判断一个数是否是奇数.偶数的速度很快 (a & 1 ) = ...
- 惠普电脑win10关闭自动调节亮度
自动调节亮度真的太烦人了,突然从亮的画面变暗,又从暗的亮度变量,眼睛受不了.但是试了很多种方法都不行. 方法 第一种: 有一些电脑是有在设置--->显示界面--->有一个 关闭自动调节 按 ...
- TCP UDP协议的三次握手
接触网络协议栈TCP/IP的人,就一定绕不开的一个话题就是TCP的三次握手.下面我将简单介绍一下. 三次握手流程的本质,可以这么理解:TCP的三次握手其实是双方各一次握手,各一次确认,只是其中一次握手 ...
- Struts(四)
1.Struts 2提供了非常强大的类型转换功能,提供了多种内置类型转换器,也支持开发自定义类型转换器2.Struts 2框架使用OGNL作为默认的表达式语言 ==================== ...
- Codeforces_731_B
http://codeforces.com/problemset/problem/731/B 模拟模拟. #include<iostream> #include<cstring> ...