扩展方法的变量作用域
本文关键字:作用域 变量 方法 扩展 | 更新日期: 2023-09-27 18:05:50
我有一件有趣的事,我想更深入地了解一下。
我有一个扩展类扩展了int:
public static class MyExtension
{
public static void GetProp(this int i, MyObject o)
{
var val = i;
o.sum = i;
}
}
使用类作为其参数之一:
public class MyObject
{
public int sum { get; set; }
}
现在,让我们看看单元测试类:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void test()
{
int a = 1;
int b = 2;
int sum = 0;
Add(a, b, sum);
//这里,sum=3,但执行后,sum将失去它的值和保留值sum = 0
int test = 4;
MyObject obj = new MyObject();
test.GetProp(obj);
但是在上面的代码中,当我使用扩展传递变量时方法,即对象。sum保留其值obj。sum = 4。我什么都不传引用值。代码的第一部分似乎跟在通过值传递。但是扩展方法的第二部分,值就像传递ByRef
一样保留
string s = sum.ToString();
string p = obj.sum.ToString();
}
private void Add(int x, int y, int sum)
{
sum = x + y;
}
}
有人能解释一下这背后的机制吗?由于
所有参数都是按值发送的,除非您使用ref
或out
关键字指定它们。按值传递参数意味着复制该值。
然而,当你按值传递一个对象时,被复制的不是对象,而是引用。这意味着您对同一个对象有两个引用,一个在obj
变量中,一个在o
参数中,但只有一个对象。
当扩展方法访问对象时,它是与方法外部相同的对象。当您稍后使用obj
变量访问该属性时,使用o
参数对其所做的任何更改都是可见的。
这是通过引用传递和传递引用对象(class
)之间的区别。在GetProp
中,您没有修改引用obj
,您正在修改由obj
引用的MyObject
实例。
如果我理解你的问题,你对为什么sum
变量在按值传递时不改变感到困惑,但是当obj
通过引用传递时,obj.sum
属性确实保留其值。其他答案很好地解释了这一点。
在您的问题中,您通过值传递参数作为接收器,这使您的问题有点混乱。你的问题似乎是,"为什么当我正常传递时,它被视为按值处理,但当我作为接收者传递给扩展方法时,它是按引用处理?"
啊。试着给接收者赋一个新值,看看调用现场会发生什么:
public static void GetProp(this int i, MyObject o)
{
o.sum = i;
i = 5000;
}
您将发现调用站点的变量test
不受此影响,因为接收者也是按值传递的 !