我理解c#(一): 参数传递和变量复制之间的关系
2010-03-18 18:08
337 查看
1.当参数是值类型与引用类型的区别和联系
2.当参数string的时候与值类型的区别
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace ConsoleCSharp
{
class classtest
{
public int test;
public string str;
public classtest()
{
test = 0;
str = "";
}
}
struct structtest
{
public int test;
public string str;
}
class Program
{
// ==与Equals一致,对值类型比较的是值相等,对于引用类型比较的是两地址是否相等
// 对于预定义的值类型,如果操作数的值相等,则相等运算符 (==) 返回真,否则,返回假。
// 对于除 string 类型以外的引用类型,如果两个操作数引用相同的对象,则 == 返回真。
// 对于 string 类型,== 将比较字符串的值。
// public static bool ReferenceEquals( object left, object right );
//这个函数就是判断两个引用类型对象是否指向同一个地址。有此说明后,就确定了它的使用范围,即只能对于引用类型操作。
//那么对于任何值类型数据操作,即使是与自身的判别,都会返回false。这主要因为在调用此函数的时候,值类型数据要进行装箱操作
static void Main(string[] args)
{
classtest ct = new classtest();
changeValue(ct);
classtest ct1 = ct;
Console.WriteLine("class : {0} {1} {2}", ct1 == ct, ct1.Equals(ct), object.ReferenceEquals(ct1, ct)); //True True
Console.WriteLine("{0} {1}", ct.test, ct.str);
// 首先在C#中传递方法参数缺省是“值拷贝”模式,也就是说对于值类型(ValueType)变量直接拷贝一份,
// 而对于引用类型则拷贝一个指向同一对象的引用副本传递给方法,因此即使不使用ref关键字,
// 我们也可以在方法内部改变该引用所指向对象的内部状态
structtest st = new structtest();
changeValue(st);
structtest st1 = st;
Console.WriteLine("struct : {0} {1} ", st1.Equals(st), object.ReferenceEquals(st1, st));
Console.WriteLine("{0} {1}", st.test, st.str);
int i = 0;
int j = i;
Console.WriteLine("int : {0} {1} {2}", i == j, i.Equals(j), object.ReferenceEquals(i, j));
changeValue(i);
Console.WriteLine(i);
string ss = "ss";
string ss2 = ss;
Console.WriteLine("string {0} {1} {2}", ss2 == ss, ss2.Equals(ss), object.ReferenceEquals(ss2, ss));
changeValue(ss);
Console.WriteLine(ss);
// string对象保存在堆上而不是堆栈上,是引用类型的,因而当把一个字符串变量赋给另一个字符串时,
// 会得到对内存中同一个字符串的两个引用.
//然后,修改其中一个字符串,注意这会创建一个完全新的string对象,而另一个字符串没改变!
}
static void changeValue(classtest t)
{
t.test += 100;
t.str += "class";
}
static void changeValue(int i)
{
i += 100;
}
static void changeValue(string i)
{
i += "string";
}
static void changeValue(structtest t)
{
t.test += 200;
t.str += "struct";
}
}
}
2.当参数string的时候与值类型的区别
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace ConsoleCSharp
{
class classtest
{
public int test;
public string str;
public classtest()
{
test = 0;
str = "";
}
}
struct structtest
{
public int test;
public string str;
}
class Program
{
// ==与Equals一致,对值类型比较的是值相等,对于引用类型比较的是两地址是否相等
// 对于预定义的值类型,如果操作数的值相等,则相等运算符 (==) 返回真,否则,返回假。
// 对于除 string 类型以外的引用类型,如果两个操作数引用相同的对象,则 == 返回真。
// 对于 string 类型,== 将比较字符串的值。
// public static bool ReferenceEquals( object left, object right );
//这个函数就是判断两个引用类型对象是否指向同一个地址。有此说明后,就确定了它的使用范围,即只能对于引用类型操作。
//那么对于任何值类型数据操作,即使是与自身的判别,都会返回false。这主要因为在调用此函数的时候,值类型数据要进行装箱操作
static void Main(string[] args)
{
classtest ct = new classtest();
changeValue(ct);
classtest ct1 = ct;
Console.WriteLine("class : {0} {1} {2}", ct1 == ct, ct1.Equals(ct), object.ReferenceEquals(ct1, ct)); //True True
Console.WriteLine("{0} {1}", ct.test, ct.str);
// 首先在C#中传递方法参数缺省是“值拷贝”模式,也就是说对于值类型(ValueType)变量直接拷贝一份,
// 而对于引用类型则拷贝一个指向同一对象的引用副本传递给方法,因此即使不使用ref关键字,
// 我们也可以在方法内部改变该引用所指向对象的内部状态
structtest st = new structtest();
changeValue(st);
structtest st1 = st;
Console.WriteLine("struct : {0} {1} ", st1.Equals(st), object.ReferenceEquals(st1, st));
Console.WriteLine("{0} {1}", st.test, st.str);
int i = 0;
int j = i;
Console.WriteLine("int : {0} {1} {2}", i == j, i.Equals(j), object.ReferenceEquals(i, j));
changeValue(i);
Console.WriteLine(i);
string ss = "ss";
string ss2 = ss;
Console.WriteLine("string {0} {1} {2}", ss2 == ss, ss2.Equals(ss), object.ReferenceEquals(ss2, ss));
changeValue(ss);
Console.WriteLine(ss);
// string对象保存在堆上而不是堆栈上,是引用类型的,因而当把一个字符串变量赋给另一个字符串时,
// 会得到对内存中同一个字符串的两个引用.
//然后,修改其中一个字符串,注意这会创建一个完全新的string对象,而另一个字符串没改变!
}
static void changeValue(classtest t)
{
t.test += 100;
t.str += "class";
}
static void changeValue(int i)
{
i += 100;
}
static void changeValue(string i)
{
i += "string";
}
static void changeValue(structtest t)
{
t.test += 200;
t.str += "struct";
}
}
}
相关文章推荐
- python函数参数是值传递还是引用传递(以及变量间复制后是否保持一致):取决于对象内容可变不可变
- c#winform编程 窗体之间传递参数问题总结(转)
- 用"堆栈区数据复制"理解Java赋值和参数传递机制的心得
- 深入理解C#之 参数传递 ref out params
- js--变量的复制与函数参数的传递
- python函数参数是值传递还是引用传递(以及变量间复制后是否保持一致):取决于对象内容可变不可变
- C# 同一应用程序域不同线程之间的参数传递方式
- c#winform编程 窗体之间传递参数问题总结(转)
- 6: 理解C#中几个“等价”概念之间的关系
- 理解C#中参数的值和引用以及传递结构和类引用的区别
- JS变量复制和参数传递
- C# 同一应用程序域不同线程之间的参数传递方式
- 转: 用”堆栈区数据复制”理解Java赋值和参数传递机制的心得
- 深入理解C#之 参数传递 ref out params【转】
- C# 参数传递、引用传递的一些个人理解
- 用"堆栈区数据复制"理解Java赋值和参数传递?机制的心得
- c# winform窗体之间传递参数的几种方法
- C#委托本质探索 七、方法变量作为函数参数传递
- C#中有关于:按 值 和 引用 传递参数 的理解
- 浅析JavaScript中的变量复制、参数传递和作用域链