我有一些有趣的东西,我想更深入地了解。
我有一个扩展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失去其值,并且保留值总和= 0
int test = 4;
MyObject obj = new MyObject();
test.GetProp(obj);
但是在上面的代码中,当我使用扩展名传递变量时方法,obj.sum保留其值obj.sum = 4。我没有通过参考价值。代码的第一部分似乎遵循通过ByVal。但是扩展方法的第二部分,值保留,就像其作为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
参数中,但只有一个对象。
当扩展方法访问该对象时,它与方法外部的对象相同。使用o
参数对属性进行的任何更改在以后使用obj
变量进行访问时都是可见的。
这是通过引用传递和传递参考对象(class
)之间的差异。在GetProp
中,您不是在修改引用obj
,而是在修改MyObject
引用的obj
实例。
[如果我理解您的问题,您会感到困惑,为什么sum
变量在通过值传递时没有更改,但是obj.sum
属性在通过引用传递obj
时仍保留其值。其他答案很好地解释了这一点。
在您的问题中,您按值作为接收者]传递了一个参数,这使您的问题有些困惑。您的问题似乎是:“为什么当我正常通过时,将其视为按值,但是当我作为接收器传递给扩展方法时,将其作为按引用吗?”
啊尝试为接收方分配一个新值,并查看呼叫现场发生的情况:
通过值传递了接收者!public static void GetProp(this int i, MyObject o) { o.sum = i; i = 5000; }
您会发现呼叫站点的变量
test
不受此影响,因为也