C#中如何让外部赋值的匿名函数访问所属对象的属性?
C#中如何让外部赋值的匿名函数访问所属对象的属性?
嗨,这个场景我之前写代码时也遇到过,其实有几种很实用的解决办法,我给你详细说下:
方法一:直接捕获局部的A实例变量
你可以在匿名函数里直接引用创建A实例时的局部变量a,这样就能精准访问到这个实例的Param属性了,代码调整成这样:
class B { public B() { var a = new A() { Param = 100, DoSomething = () => Debug.Print(a.Param.ToString()) }; } }
这里的核心是匿名函数捕获了局部变量a,而a正好指向你创建的那个A类实例。只要之后你不把a重新赋值成别的A实例,调用DoSomething的时候就会正确访问到对应实例的Param。
方法二:把DoSomething的初始化逻辑放到A类内部(更推荐)
如果想更贴合封装的设计思路,避免外部依赖局部变量,你可以在A类里加一个专门的方法来初始化DoSomething。因为在A类内部,this天然指向当前A的实例,完全不会和B类的上下文混淆。
先修改A类:
class A { public int Param { get; set; } public Action DoSomething { get; set; } public void SetupDoSomething() { // 这里的Param等价于this.Param,直接指向当前A实例的属性 DoSomething = () => Debug.Print(Param.ToString()); } }
然后在B类里这样使用:
class B { public B() { var a = new A() { Param = 100 }; a.SetupDoSomething(); } }
这种方式更稳妥,DoSomething的逻辑完全由A类自己掌控,不管外部怎么创建A实例,都不会搞错上下文。
方法三:拆分实例初始化和DoSomething赋值
要是不想改动A类的结构,也可以不用对象初始化器,先创建A实例再单独赋值DoSomething,写法上会更直观:
class B { public B() { var a = new A(); a.Param = 100; a.DoSomething = () => Debug.Print(a.Param.ToString()); } }
这个和方法一本质逻辑一样,只是把初始化拆成了两步,避免在对象初始化器里直接引用还没完全初始化的变量(虽然C#允许这么做,但不少开发者觉得分开写可读性更高)。
最后提个小细节:如果你的DoSomething生命周期比局部变量a长——比如把它赋值给了某个长期存在的全局变量,那a指向的A实例会因为被匿名函数捕获而无法被垃圾回收,复杂场景下要留意这个潜在的内存泄漏风险。
备注:内容来源于stack exchange,提问作者Jake
相关产品推荐
相关产品推荐

