C#扩展方法如何为this变量(父级变量)赋值?
解决C#值类型扩展方法无法直接修改原变量的问题
首先得说清楚为什么你原来的代码做不到:int是值类型,当你把它传递给方法(包括扩展方法)时,会自动创建一个副本。你的Add扩展方法里操作的只是这个副本,原变量i根本没被改动,所以必须赋值才能让i变成新值。
那怎么实现你想要的i.Add(2)直接修改原变量的效果呢?这里有两个可行的方案:
方案一:使用带ref参数的静态方法(接近扩展方法体验)
虽然C#不允许扩展方法的this参数用ref修饰,但我们可以写一个接受ref int的静态方法,调用时显式传递ref关键字:
public static class IntHelpers { public static void Add(ref int target, int valueToAdd) { target += valueToAdd; } }
调用代码:
int i = 9; IntHelpers.Add(ref i, 2); // 直接修改原i的值 Console.WriteLine(i); // 输出11
这种方式不用包装类,但调用时需要写ref关键字,和你想要的纯扩展方法语法略有区别。
方案二:创建可变包装类+扩展方法(完美匹配调用语法)
如果想严格保留i.Add(2)的调用方式,我们可以自己写一个可变的引用类型包装类,把int包进去,然后给这个包装类写扩展方法:
第一步:定义包装类
public class MutableInt { public int Value { get; set; } public MutableInt(int initialValue) { Value = initialValue; } // 可选:重写ToString,直接输出数值 public override string ToString() { return Value.ToString(); } }
第二步:写扩展方法
public static class MutableIntExtensions { public static void Add(this MutableInt mutableInt, int valueToAdd) { mutableInt.Value += valueToAdd; } }
调用代码
var i = new MutableInt(9); i.Add(2); // 直接修改包装类内部的Value值 Console.WriteLine(i); // 输出11
这个方案完全符合你的需求,因为MutableInt是引用类型,扩展方法里操作的是同一个对象的内部属性,所以原变量的状态会直接被修改。
补充说明:为什么值类型做不到直接修改?
C#里值类型的实例本身就是数据,而引用类型的实例是指向数据的指针。扩展方法对于值类型来说,拿到的只是数据的副本,修改副本不会影响原数据;而引用类型拿到的是指针的副本,指向的还是同一个数据对象,所以修改对象内部值会生效。
内容的提问来源于stack exchange,提问作者Garuda prasad K
相关产品推荐
相关产品推荐

