C# 中 方法调时的参数若是一个对象,使用 in 与 ref 或完全不用 in/ref 的区别
in/ref 不用的话,传入的是对象的引用值。如:Call( Class c )。在方法中若将此参数变量赋值为null,并不会影响到传入前外部的实例引用。也就是说,在方法中这个变量是一个局部引用变量。
类似于 C/C++ 中,传入一个对象或 结构 的指针地址。在方法里把这个地址改成0后,方法外保存实例的变量值并不会被修改。
void changeTest(testClass c) { c.i = 900; c = null; } ... void foo() { testClass t = new testClass(); changeTest(t); Console.WriteLine("{0}", t.i ); //这里输出900, t值并不为null,还是有效的 }
用 in 的话,与上面一种情况一样,传入的是对象的引用值。但编译器为了合理化 in 的意思,会在编译时进行检查,让这个引用变量值在此方法内不能被修改。
void changeTestIn(in c)
{
c.i = 300;
c = new testClass(); //在编译时,这里出会现问题,编译不过
}
用 ref 的话,必须引用到一个实体变量,无论这个变量是存贮什么。编译器为了合理化 ref 的意思,会在编译时进行检查,若传入 一个 null 值,它只是一个关键字,不存一个实体变量的地址,说明不可能被 ref,编译时就会报错。但若 可以引用到某个实体变量,就算变量的值为 null,也是可以编译通过的。因为存在一个实体变量可以被 ref。
传入后方法内部可以把这个变量值改为 null,就等于把这个实体变量的值 为null了,此时这个变量就不再指向原来那个实体了。那个实体若在程序中没有其它变量再指向它,因为被引用为0次,不久后可能就会被自动GC。
void changeTestRefNULL(ref testClass c)
{
if( null != c)
c.i = 300;
}
void changeTestRef(ref testClass c)
{
c.i = 200;
}
void changeTestRefToNULL(ref testClass c)
{
c.i = 1000;
c = null; //可以的
}
void test()
{
testClass t = null;
changeTestRefNULL(ref t); //ok
changeTestRefNULL(ref null); //在编译时,这里会出问题,编译不过
t = new testClass();
changeTestRef(ref t);
Console.WriteLine("after changeTestRef(), i = {0}", t.i); // 输出 after changeTestRef(), i = 200
changeTestRefToNULL(ref t);
Console.WriteLine("after changeTestRefToNULL(), i = {0}", t.i); //运行时出错,因为 t 此时为 null
}

浙公网安备 33010602011771号