首页 新闻 会员 周边

请问委托中传递对象参数值问题

0
悬赏园豆:10 [待解决问题]

为什么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); 

    }
mysky的主页 mysky | 初学一级 | 园豆:187
提问于:2021-12-24 20:46
< >
分享
所有回答(2)
1

引用的问题,action执行的时候传递一个引用参数,这个引用之前是Test中的user
如果在action中只是给这个引用的对象字段赋值,则更改的是引用的对象的属性,就能输出ddd
如果你在action中user = new User { Name = "aaa" },则改变了这个参数的指向,将其指向了一个新的地址,Name="aaa"是这个新对象的数据,外部的user则未作任何赋值
因此,无法输出aaa

WmW | 园豆:424 (菜鸟二级) | 2021-12-27 10:00

但是 Test方法里的user不是应该指向在action invoke里新new的对象吗,从现象看,外部的user应该是没有指向 action内部new的user,不过原因是什么,回答里没有说明白。

支持(0) 反对(0) HelloLLLLL | 园豆:434 (菜鸟二级) | 2021-12-30 11:00

@HelloLLLLL: action.invoke执行时传递的user地址会赋值给action内部的一个参数变量,如果这个参数变量没有被更改,那么它指向外部的对象,当我们更改这个变量的成员时,本质上就是更改外部对象的成员,因此能输出ddd
但是,如果你在action内部更改了参数的指向,即user = new User { Name = "aaa" };,那么此时action的参数就指向了这个新new的User,你给这个User初始化的Name="aaa",并不会影响外部的user

支持(0) 反对(0) WmW | 园豆:424 (菜鸟二级) | 2022-01-06 11:22
0

//User user = new User() { };

        User user = null;

action.Invoke(user);
Console.WriteLine(user.Name);
这样写的话,会报空引用异常,说明 action里创建的对象并没有指向外部的user。为什么会这样。因为你一个句柄指向两个user对象,一个是外部的,一个是内部的,但是内部新建的ddd那个对象在lamda表达式结束后,就被回收了,剩下的就是外部的那个user对象了,明明有句柄指向的对象我认为不应该被回收才对?那么还有种可能,那就是 lamda表达式内部的作用域和外部的作用域是隔离的,你可以在程序退出Action方法后,那个内部的user对象还在不在?这些只是我的猜测,希望能提供给你一些思路。

HelloLLLLL | 园豆:434 (菜鸟二级) | 2021-12-30 11:19
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册