class Program
{
static void Main(string[] args)
{
Person p1 = new Person();
p1.Age = 10;
p1.Name = "Jim";
Console.WriteLine(p1.Age+p1.Name);
change(p1);
Console.WriteLine(p1.Age + p1.Name);
string s1 = "ssssssssssss";
Console.WriteLine(s1);
changestring(s1);
Console.WriteLine(s1); Console.ReadKey();
} static void change(Person p)
{
p.Age = 999;
p.Name = "bill gates";
}
static void changestring(string s)
{
s = "fuck you";
}
}
class Person
{
public int Age { get; set; }
public string Name { set; get; }
}
-------------------输出结果-----------------
10Jim
999bill gates
ssssssssssss
ssssssssssss我自己定义了一个Person类,两个方法
我的问题是:关于方法参数(两个方法的参数都是值传递,没有加ref和out ,但是change()方法能改变Person 变量,当changestring()方法不能改变string变量,这是为什么呢方法参数stringclass
{
static void Main(string[] args)
{
Person p1 = new Person();
p1.Age = 10;
p1.Name = "Jim";
Console.WriteLine(p1.Age+p1.Name);
change(p1);
Console.WriteLine(p1.Age + p1.Name);
string s1 = "ssssssssssss";
Console.WriteLine(s1);
changestring(s1);
Console.WriteLine(s1); Console.ReadKey();
} static void change(Person p)
{
p.Age = 999;
p.Name = "bill gates";
}
static void changestring(string s)
{
s = "fuck you";
}
}
class Person
{
public int Age { get; set; }
public string Name { set; get; }
}
-------------------输出结果-----------------
10Jim
999bill gates
ssssssssssss
ssssssssssss我自己定义了一个Person类,两个方法
我的问题是:关于方法参数(两个方法的参数都是值传递,没有加ref和out ,但是change()方法能改变Person 变量,当changestring()方法不能改变string变量,这是为什么呢方法参数stringclass
static void change(Person p) { p.Age = 999; p.Name = "bill gates"; } static void changestring(string s) { s = "fuck you"; }
前一个方法和后一个方法现在不是等价的,因为前一个是改对象内部的属性,另一个是改对象本身。
把前一个方法修改下才是等价的,你再看结果。
static void change(Person p)
{
p = new Person();
p.Age = 999;
p.Name = "bill gates";
}
比如"abc"这个字符串我想在后面加一个"d",变成"abcd"。非常可惜,由于string的实现机制,所以"abc"和"abcd"是两个完全不同的对象,所以 其实还是相当于引用本身发生了变化。
string也是引用类型,但是它跟其它引用类型有所不同,string类型变量的值直接是存储在栈中,通过函数传递的是s1的副本,也是就说传递之前会在栈里面新建一个s1的副本传递到changestring函数中,在
changestring函数中对s1做的任何修改都不会影响Main函数中的s1,所以在Main函数在s1修改前后的值都是不变的
{
static void Main(string[] args)
{
Person p1 = new Person();
p1.Age = 10;
p1.Name = "Jim";
Console.WriteLine(p1.Age + p1.Name);
change(p1);
Console.WriteLine(p1.Age + p1.Name);
string s1 = "ssssssssssss";
Console.WriteLine(s1);
changestring(s1);
Console.WriteLine(s1); Console.ReadKey();
} static void change(Person p)
{
p = new Person(); //这里如果new出来一个,那主是代表新的person对象了
p.Age = 999;
p.Name = "bill gates";
}
static void changestring(string s)
{
s = "fuck you";
}
}
class Person
{
public int Age { get; set; }
public string Name { set; get; }
}
我用你的思路,弄了一个你“认为”会错的东西,仔细看代码,估计能解决你的问题
显示结果:
10Jim
10Jim
ssssssssssss
ssssssssssss上面如果不new一个persion对象,那么指针还是指向Person p1 = new Person();这里
如果改成你要的可以这样:
class Program
{
static void Main(string[] args)
{
Person p1 = new Person();
p1.Age = 10;
p1.Name = "Jim";
Console.WriteLine(p1.Age + p1.Name);
change(p1);
Console.WriteLine(p1.Age + p1.Name);
string s1 = "ssssssssssss";
Console.WriteLine(s1);
s1 = changestring(s1);
Console.WriteLine(s1); Console.ReadKey();
} static void change(Person p)
{
//p = new Person(); //这里如果new出来一个,那主是代表新的person对象了
p.Age = 999;
p.Name = "bill gates";
}
static string changestring(string s)
{
s = "fuck you";
return s;
}
}
class Person
{
public int Age { get; set; }
public string Name { set; get; }
}
输出:
10Jim
999bill gates
ssssssssssss
fuck you
string类型比较特殊,事实上任何一个string都是全局的。所谓的修改string的值,其实就是把引用更改到另一个string上去。
事实上平时你不需要关心这个,但是有一种情况必须知道,就是lock。
一般用lock来锁引用类型的对象,但是不应该去lock一个string的对象,因为string是全局的,
string a = "abc";
所以如果你lock(a),事实上"abc"这个对象就锁住了,另外一个地方
string b = "abc";
lock(b);
这时a和b其实是锁的同一个对象。所以lock是不推荐去锁string的。