为什么aaa 是 null,ddd是有值的啊 怎么理解
static void Main(string[] args)
{
Test((user) =>
{
user = new User { Name = "aaa" };
//user.Name = "ddd";
});
Console.ReadLine();
}
public static void Test(Action<User> action) {
User user = new User() { };
action.Invoke(user);
Console.WriteLine(user.Name);
}
引用的问题,action执行的时候传递一个引用参数,这个引用之前是Test中的user
如果在action中只是给这个引用的对象字段赋值,则更改的是引用的对象的属性,就能输出ddd
如果你在action中user = new User { Name = "aaa" },则改变了这个参数的指向,将其指向了一个新的地址,Name="aaa"是这个新对象的数据,外部的user则未作任何赋值
因此,无法输出aaa
但是 Test方法里的user不是应该指向在action invoke里新new的对象吗,从现象看,外部的user应该是没有指向 action内部new的user,不过原因是什么,回答里没有说明白。
@HelloLLLLL: action.invoke执行时传递的user地址会赋值给action内部的一个参数变量,如果这个参数变量没有被更改,那么它指向外部的对象,当我们更改这个变量的成员时,本质上就是更改外部对象的成员,因此能输出ddd
但是,如果你在action内部更改了参数的指向,即user = new User { Name = "aaa" };,那么此时action的参数就指向了这个新new的User,你给这个User初始化的Name="aaa",并不会影响外部的user
//User user = new User() { };
User user = null;
action.Invoke(user);
Console.WriteLine(user.Name);
这样写的话,会报空引用异常,说明 action里创建的对象并没有指向外部的user。为什么会这样。因为你一个句柄指向两个user对象,一个是外部的,一个是内部的,但是内部新建的ddd那个对象在lamda表达式结束后,就被回收了,剩下的就是外部的那个user对象了,明明有句柄指向的对象我认为不应该被回收才对?那么还有种可能,那就是 lamda表达式内部的作用域和外部的作用域是隔离的,你可以在程序退出Action方法后,那个内部的user对象还在不在?这些只是我的猜测,希望能提供给你一些思路。