C#(也适用其他)的初学者对string是值类型还是引用类型搞不清楚,还有对参数传递也比较迷糊
通过这个例子可能有点帮助
using System;
using System.Reflection;
using System.Runtime.InteropServices;
namespace StringTest
{
public class StringTest
{
[STAThread]
static void Main()
{
StringTest tester = new StringTest();
string str = "a test string.";
string str1 = "a test string.";//和str一样的值。
using System.Reflection;
using System.Runtime.InteropServices;
namespace StringTest
{
public class StringTest
{
[STAThread]
static void Main()
{
StringTest tester = new StringTest();
string str = "a test string.";
string str1 = "a test string.";//和str一样的值。
string str2 = str;
Console.WriteLine("str = " + str); //输出:a test string.
Console.WriteLine("str1 = " + str1); //输出:a test string.
Console.WriteLine("str2 = " + str2); //输出:a test string.
Console.WriteLine(" ");
//使用反射技术把字符串的第4个字符修改为“E”
typeof(string).InvokeMember("SetChar", BindingFlags.Default | BindingFlags.NonPublic | BindingFlags.Instance |BindingFlags.InvokeMethod, null, str, new object[]{3, 'E'});
Console.WriteLine("str = " + str); //输出:a tEst string.
Console.WriteLine("str1 = " + str1); //输出:a tEst string.
Console.WriteLine("str2 = " + str2); //输出:a tEst string.
//从上面的试验很清楚地看出string是引用类型,因为str,str1,str2 只有都指向一个对象,才会同时改变
Console.WriteLine("str = " + str); //输出:a test string.
Console.WriteLine("str1 = " + str1); //输出:a test string.
Console.WriteLine("str2 = " + str2); //输出:a test string.
Console.WriteLine(" ");
//使用反射技术把字符串的第4个字符修改为“E”
typeof(string).InvokeMember("SetChar", BindingFlags.Default | BindingFlags.NonPublic | BindingFlags.Instance |BindingFlags.InvokeMethod, null, str, new object[]{3, 'E'});
Console.WriteLine("str = " + str); //输出:a tEst string.
Console.WriteLine("str1 = " + str1); //输出:a tEst string.
Console.WriteLine("str2 = " + str2); //输出:a tEst string.
//从上面的试验很清楚地看出string是引用类型,因为str,str1,str2 只有都指向一个对象,才会同时改变
//可见在.NET中值相同的字符串在内存中是共用的。
Console.WriteLine(" ");
str2 = "aa"; //把str2的值修改为“aa”
tester.Test1(str1); //调用方法Test1
Console.WriteLine("str = " + str); //输出:a tWst string.
Console.WriteLine("str1 = " + str1); //输出:a tWst string.
Console.WriteLine("str2 = " + str2); //输出:aa
Console.WriteLine(" ");
//从上面的试验可以看出,字符串的赋值运算符是新建一个对象,而不是修改原来对象的值
//还可以看出通过值传递引用类型参数时,传递的是对其数据的引用,而不是数据本身
tester.Test2(ref str);
Console.WriteLine("str = " + str); //输出:abcM
Console.WriteLine("str1 = " + str1);//输出:a tWst string.
Console.WriteLine("str2 = " + str2);//输出:aa.
Console.WriteLine(" ");
//从上面的试验可以看出通过引用传递引用类型的作用:
//ref 方法参数关键字使方法引用传递到方法的同一个变量(既str)。
//在方法(Test2)中对参数所做的任何更改(src = "abcd")都将反映在该变量中(str)。
}
public void Test1(string src)
{
//使用反射技术把字符串的第4个字符修改为“W”
typeof(string).InvokeMember("SetChar", BindingFlags.Default | BindingFlags.NonPublic | BindingFlags.Instance |BindingFlags.InvokeMethod, null, src, new object[]{3, 'W'});
src = "abcd";
}
public void Test2(ref string src)
{
src = "abcd";
//使用反射技术把字符串的第4个字符修改为“M”
typeof(string).InvokeMember("SetChar", BindingFlags.Default | BindingFlags.NonPublic | BindingFlags.Instance |BindingFlags.InvokeMethod, null, src, new object[]{3, 'M'});
}
}
}
Console.WriteLine(" ");
str2 = "aa"; //把str2的值修改为“aa”
tester.Test1(str1); //调用方法Test1
Console.WriteLine("str = " + str); //输出:a tWst string.
Console.WriteLine("str1 = " + str1); //输出:a tWst string.
Console.WriteLine("str2 = " + str2); //输出:aa
Console.WriteLine(" ");
//从上面的试验可以看出,字符串的赋值运算符是新建一个对象,而不是修改原来对象的值
//还可以看出通过值传递引用类型参数时,传递的是对其数据的引用,而不是数据本身
tester.Test2(ref str);
Console.WriteLine("str = " + str); //输出:abcM
Console.WriteLine("str1 = " + str1);//输出:a tWst string.
Console.WriteLine("str2 = " + str2);//输出:aa.
Console.WriteLine(" ");
//从上面的试验可以看出通过引用传递引用类型的作用:
//ref 方法参数关键字使方法引用传递到方法的同一个变量(既str)。
//在方法(Test2)中对参数所做的任何更改(src = "abcd")都将反映在该变量中(str)。
}
public void Test1(string src)
{
//使用反射技术把字符串的第4个字符修改为“W”
typeof(string).InvokeMember("SetChar", BindingFlags.Default | BindingFlags.NonPublic | BindingFlags.Instance |BindingFlags.InvokeMethod, null, src, new object[]{3, 'W'});
src = "abcd";
}
public void Test2(ref string src)
{
src = "abcd";
//使用反射技术把字符串的第4个字符修改为“M”
typeof(string).InvokeMember("SetChar", BindingFlags.Default | BindingFlags.NonPublic | BindingFlags.Instance |BindingFlags.InvokeMethod, null, src, new object[]{3, 'M'});
}
}
}