值类型与引用类型的最大区别是值类型被分配的存贮空间是在栈里,引用类型被分析的空间是在堆内存中。
那什么类型是值类型有哪些,哪些是引用类型呢?
值类型:基元类型、枚举类型、结构体。
引用类型:类、字符串、标准模块、接口、数组和委托。
那怎么根据它们的表相来区别值类型与引用类型呢?
方案1:使用系统Type属性判定
public bool IsValueType<T>()
{return typeof(T).IsValueType;
}
方案2:用是否可为空来判断(歪招)
值引用默认是不能为空的。如int i=null;在VS的编译器里就会提示
引用类型是默认可以为空的,如string str=null,是正确的。
关于值引用与类型引用,除了编程时经常需要区分以外,还经常被用来考察一个程序员的基本功,出现在面试题或者是考试中,怎么考察呢?
依据:值类型的变量直接包含它们的数据,而引用类型的变量存储对它们的数据的引用,后者称为对象。对于引用类型,两个变量可能引用同一个对象,因此对一个变量的操作可能影响另一个变量所引用的对象。
可能你就会遇到以下一段代码,让你写出最后的输出结果:
public void PrintTheResultString()
{ Console.WriteLine("string类型赋值"); string str = "Init"; Console.WriteLine("原始:"+str); Process(str); Console.WriteLine("结果:"+str); } private void Process(string str) {str = "changed";
}
public void PrintTheResultInt()
{ Console.WriteLine("int类型赋值");int i=0;
Console.WriteLine("原始:" + i); Process(i); Console.WriteLine("结果:" + i); } private void Process(int i) { i = 2; }
public void PrintTheResultDateTime()
{ Console.WriteLine("DateTime类型赋值"); DateTime dt = DateTime.Parse("2000-01-01"); Console.WriteLine("原始:" + dt.ToString("yyyy-MM-dd")); Process(dt); Console.WriteLine("结果:" + dt.ToString("yyyy-MM-dd")); } private void Process(DateTime dt) { dt = DateTime.Parse("2001-01-01"); }
public void PrintTheResultArrayList()
{ Console.WriteLine("ArrayList类型赋值"); ArrayList arraylist = new ArrayList(); Console.WriteLine("原始:" + arraylist.Count); Process(arraylist); Console.WriteLine("结果:" + arraylist.Count); } private void Process(ArrayList arraylist) {arraylist.Add("1");
}
在以上四段程序,输出结果是什么呢?
可以看出来,除了ArrayList类型的赋值,值进行改变外,其它都是保持初始状态,难道string,int,DateTime都是值类型吗?
使用方案1,你就不难发现,string是引用类型,他是值类型中的间谍。string 是引用类型,但它的使用与值类型的使用完全一样,是把它进行了仿值类型编造。
Int 是基元类型,DateTime是结构体,他们两个的确是名副其实的值类型。
行了,就这么多吧,下回我就说一说可空类型吧。