C# 值类型和引用类型
2011-08-16 23:31 DylanChan 阅读(279) 评论(0) 收藏 举报◆值类型直接存储其值,变量本身就包含了其实例数据,而引用类型保存的只是实例数据的内存引用。因此,一个值类型变量就永远不会影响到其他的值类型变量,而两个引用类型变量则很有可能指向同一地址,从而发生相互影响。
◆从内存分配上来看,值类型通常分配在线程的堆栈(Sack)上,作用域结束时,所占空间自行释放,效率高,无需进行地址转换,而引用类型通常分配在托管堆(Heap)上,由GC来控制其回收,需要进行地址转换,效率降低,这也正是c#需要定义两种数据类型的原因之一。
◆值类型均隐式派生自System.ValueType,而System.ValueType又直接派生于System.Object,每种值类型均有一个隐式的默认构造函数来初始化该类型的默认值,注意所有的值类型都是密封(sealed)的,所以无法派生出新的值类型。而且System.ValueType本身是一个类类型,而不是值类型,因为它重写了object的Equals()方法,所以对值类型将按照实例的值来比较,而不是比较引用地址。
◆C# 的统一类型系统,使得值类型可以转化为对象来处理,这就是常说的装箱和拆箱。由于装拆箱需要装建全新对象或做强制类型转换,这些操作所需时间和运算要远远大于赋值操作,因此不提倡使用它,同时也要尽量避免隐式装拆箱的发生。
栈是操作系统分配的一个连续的内存区域,用于快速访问数据。因为值类型的容量是已知的,因此它可存储在栈上。
托管堆是CLR在应用程序启动时为应用程序预留的一块连续内存区,是用于动态内存分配的内存区,引用类型的容量只有到运行时才能确定,所有用堆来存储引用类型。
string类型
class Program
{
static void Main()
{
string str1 = "abc";
string str2 = str1;
str1 = "123";
Console.WriteLine(str2); //输出结果是abc,改变str1的值对str2没有影响。
string a = "hello";
string b = "h";
// Append to contents of 'b'
b += "ello";
Console.WriteLine(a == b); //输出结果是True
}
}
class和struct的语法基本相同,从声明到使用,都很相似。但是struct的约束要比class多,理论上,struct能做到的class都能做到,但class能做到的stuct却不一定做的到,也就是说struct都能被class所代替。那么为什么还要使用struct呢?存在即是合理的,struct在很多方面有着性能优势。让我们看看它们的主要区别在哪里?
struct AStruct
{
int aField;
}
class AClass
{
int aField;
}
class MainClass
{
public static void Main()
{
AClass b = null; // No error.
AStruct s = null; // Error [ Cannot convert null to 'AStruct' because it is a value type ].
}
}
class MyClass
{
int myVar = 10; // no syntax error.
}
struct MyStruct
{
int myVar = 10; // 结构中不能有实例字段初始值设定项
}
class MyClass
{
int myVar = 10;
public MyClass() // no syntax error.
{
// statements
}
}
struct MyStruct
{
int myVar;
public MyStruct() //结构不能包含显式的无参数构造函数
{
// statements
}
}
class Program
{
static void Main()
{
MyClass mc = new MyClass(); //类使用前必须new关键字实例化
Console.WriteLine(mc.myVar);
MyStruct ms;
ms.myVar = 100;
}
}
class MyClass
{
public int myVar = 10;
}
struct MyStruct
{
public int myVar;
}
class MyClass
{
int myInt;
string myString;
public MyClass(int aInt)
{
//Statement
}
}
struct MyStruct
{
public int myInt;
public string myString;
public MyStruct(int aInt)
{
myInt = 3;
myString = "abc";
}
}
浙公网安备 33010602011771号