1、首先来解释一下C#中的类型
在C#中每一种类型要么是值类型,要么是引用类型。所以每个对象要么是值类型的实例,要么是引用类型的实例。并且在C#中对象的分配模式取决于对象的实现方式,即值类型使用静态分配,引用类型使用动态分配。即便是在进行值类型实例化的时候使用new关键字进行实例化也不会改变实例的分配方式,在这种情况下new操作法仅起到向构造函数传递参数的作用。
C#中的引用是一个不同于引用类型的概念,它介于C++中的指针和引用之间。可以是一个到对象的引用,所有该对象的可访问成员都可以通过“.”操作法进行访问;引用可以为空;引用可以被修改(这里要注意在方法参数中使用ref关键字的结果) ;不能够访问对象的物理空间,即对象的实际地址。
2、引用类型和值类型代码示例
-
- struct TypeVal
- {
- public int _i;
- public TypeVal(int i) { _i = i; }
- }
-
- class TypeRef
- {
- public int _i;
- public TypeRef(int i) { _i = i; }
- }
-
- class Program
- {
- static void Main()
- {
-
- TypeVal v1 = new TypeVal(6);
-
-
- TypeVal v2 = v1;
-
- v2._i = 10;
-
- System.Diagnostics.Debug.Assert(v1._i == 6 && v2._i == 9);
-
-
-
- TypeRef r1 = new TypeRef(6);
-
- TypeRef r2 = r1;
-
- r2._i = 11;
-
- System.Diagnostics.Debug.Assert(r1._i == 11 && f2._i == 11);
- }
- }
3、在方法中修改引用类型的范例
- class RefTest
- {
- public int Number = 0;
-
-
-
-
- public static void fct(ref RefTest RefA, RefTest RefB)
- {
- if (RefA == null)
- RefA = new RefTest();
- if (RefB == null)
- RefB = new RefTest();
- }
- }
-
-
- class Program
- {
- static void Main(string[] args)
- {
- f_RefTest();
- }
- static void f_RefTest()
- {
- RefTest refA = null;
- RefTest refB = null;
- RefTest.fct(ref refA, refB);
-
- if (refA == null)
- System.Console.WriteLine("refA is null");
- else
- System.Console.WriteLine("refA now references the RefTest allocated in fct");
- if (refB == null)
- System.Console.WriteLine("refB is null");
- else
- System.Console.WriteLine("refB now references the RefTest allocated in fct");
-
- System.Console.ReadLine();
- }
输出结果如下:
可见对于添加ref关键字的引用类型,其效用就在于能够在方法内部对引用的指向进行修改。如果不添加ref关键字,那么其作用仅限于通过引用修改该引用所指向的对象的内部状态(对象的字段等)。
4、ref 与string
C#中string类具有三大特点,即sealed、等价比较、实例创建后的不可变性。
- static void TestString(ref string str1, string str2)
- {
-
-
- str1 = "new str1";
-
- str2 = "new str2";
- }
-
- static void Main(string[] args)
- {
-
-
- string str1 = "str1";
- string str2 = "str2";
-
- TestString(ref str1, str2);
-
- Console.WriteLine(str1);
- Console.WriteLine(str2);
- Console.ReadLine();
- }
5、总结
ref(引用型参数)对方法的数据传递是通过实际值的内存地址来传递的,所以说对其的改变将影响到它实际的内存地址。如果ref 作用于引用类型,那么意味着可以修改引用本身的值,即修改引用的指向。