作者:萧勇志762852 | 来源:互联网 | 2023-10-12 04:54
分配在栈上、派生于System.ValueType的值类型:●简单类型,比如int,uint,byte,sbyte,short,long,ulong,char,float,do
分配在栈上、派生于System.ValueType的值类型:
●
简单类型,比如int,uint,byte,sbyte,short,long,ulong,char,float,double,decmial,bool都属于值类型。简单类型对应BCL基类库的别名,比如byte对应System.Byte,short对应System.Int16等。
●
结构和枚举属于值类型。
什么是BCL基类库:
Base Class
Library基类库,即mscorlib.dll这个程序集中包含类库。不管项目的"引用"文件夹里是否引用,默认是引用进来的。C#中的关键字,比如int,
string都会被映射到BCL基类库中的对应类型。BCL也为中间语言CIL提供基础支持。
栈(Stack)和堆(Heap):
title="栈和堆" border="0" alt="栈和堆" src="https://img8.php1.cn/3cdc5/1e804/3b4/3ced152850f49b5a.jpeg"
>
在对变量操作前是不会入栈的
展开using System;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
MyCuteCat cat;
}
}
public struct MyCuteCat
{
public int _age;
public MyCuteCat(int age)
{
this._age = age;
}
}
}
title="1" border="0" alt="1" src="https://img8.php1.cn/3cdc5/1e804/3b4/d64dde1dbf021096.jpeg"
>
一旦对变量操作,就会有出栈和入栈操作
展开 class Program
{
static void Main(string[] args)
{
MyCuteCat cat;
cat._age = 1;
Console.WriteLine(cat._age);
Console.ReadKey();
}
}
title="2" border="0" alt="2" src="https://img8.php1.cn/3cdc5/1e804/3b4/d3f8eff0880a6e9b.jpeg"
>
引用类型初始化需要new对象,否则报错
把结构类型改成class,生成的时候会出现编译错误。
展开using System;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
MyCuteCat cat;
cat._age = 1;
Console.WriteLine(cat._age);
Console.ReadKey();
}
}
public class MyCuteCat
{
public int _age;
public MyCuteCat(int age)
{
this._age = age;
}
}
}
title="3" border="0" alt="3" src="https://img8.php1.cn/3cdc5/1e804/3b4/0756953c75b2ec31.jpeg"
>
所有的元素在使用前必须初始化,否则报错
把cat._age = 1;注释掉。
展开using System;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
MyCuteCat cat;
//cat._age = 1;
Console.WriteLine(cat._age);
Console.ReadKey();
}
}
public struct MyCuteCat
{
public int _age;
public MyCuteCat(int age)
{
this._age = age;
}
}
}
title="4" border="0" alt="4" src="https://img8.php1.cn/3cdc5/1e804/3b4/0e0063300a1981e1.jpeg"
>
对结构而言,在调用方法之前需要对所有字段进行赋值
展开using System;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
MyCuteCat cat;
//cat._age = 1;
//Console.WriteLine(cat._age);
cat.SayHi();
Console.ReadKey();
}
}
public struct MyCuteCat
{
public int _age;
public MyCuteCat(int age)
{
this._age = age;
}
public void SayHi()
{
Console.WriteLine("我是猫小姐,我今年" + _age + "岁了");
}
}
}
title="5" border="0" alt="5" src="https://img8.php1.cn/3cdc5/1e804/3b4/bf0c8b3f57156343.jpeg"
>
去掉cat._age = 1;的注释,运行。
title="6" border="0" alt="6" src="https://img8.php1.cn/3cdc5/1e804/3b4/6c6a7f85b360a364.jpeg"
>
如果要对结构的每个字段赋值会很麻烦。
结构类型的构造函数
□ 使用结构的构造函数对结构字段进行初始化
是由编译器隐式为结构类型创建的。在构造函数中对结构类型进行初始化,值类型的初始值是0,引用类型的初始值是null。
注意:不可以对结构类型显式地声明构造函数。
展开using System;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
MyCuteCat cat = new MyCuteCat();
//cat._age = 1;
//Console.WriteLine(cat._age);
cat.SayHi();
Console.ReadKey();
}
}
public struct MyCuteCat
{
public int _age;
public MyCuteCat(int age)
{
this._age = age;
}
public void SayHi()
{
Console.WriteLine("我是猫小姐,我今年" + _age + "岁了");
}
}
}
运行结果:
title="7" border="0" alt="7" src="https://img8.php1.cn/3cdc5/1e804/3b4/89d9e6c99cc0a4a0.jpeg"
>
IL部分:
title="8" border="0" alt="8" src="https://img8.php1.cn/3cdc5/1e804/3b4/ffe6ef050959240f.jpeg"
>
可见:
MyCuteCat
cat意味着在线程栈上创建了一个类型为MyCuteCat的变量cat,并入栈。
new
MyCuteCat()并不是创建实例,也不不会分配内存,仅仅是调用结构的构造函数对字段进行初始化。
□ 如果没有声明局部变量,会创建一个临时变量
展开using System;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new MyCuteCat()._age);
Console.ReadKey();
}
}
public struct MyCuteCat
{
public int _age;
public MyCuteCat(int age)
{
this._age = age;
}
public void SayHi()
{
Console.WriteLine("我是猫小姐,我今年" + _age + "岁了");
}
}
}
title="9" border="0" alt="9" src="https://img8.php1.cn/3cdc5/1e804/3b4/6e0df235521a6e92.jpeg"
>
□ 通过结构的构造函数为结构字段赋初值
展开using System;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
MyCuteCat cat = new MyCuteCat(10);
cat.SayHi();
Console.ReadKey();
}
}
public struct MyCuteCat
{
public int _age;
public MyCuteCat(int age)
{
this._age = age;
}
public void SayHi()
{
Console.WriteLine("我是猫小姐,我今年" + _age + "岁了");
}
}
}
title="10" border="0" alt="10" src="https://img8.php1.cn/3cdc5/1e804/3b4/abed74f5f54bc6a0.jpeg"
>
IL部分:
title="11" border="0" alt="11" src="https://img8.php1.cn/3cdc5/1e804/3b4/11946da445f77e62.jpeg"
>
※参考资料
《.NET之美》--张子阳,感谢写了这么好的书!
02值类型,布布扣,bubuko.com