C# 扩展方法的变量范围
我有一些有趣的东西,我想更深入地了解一下 我有一个扩展int的扩展类:C# 扩展方法的变量范围,c#,scope,extension-methods,C#,Scope,Extension Methods,我有一些有趣的东西,我想更深入地了解一下 我有一个扩展int的扩展类: public static class MyExtension { public static void GetProp(this int i, MyObject o) { var val = i; o.sum = i; } } 使用类作为其参数之一的: public class MyObject {
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
但是在上面的代码中,当我使用扩展名传递变量时
方法,obj.sum保留其值obj.sum=4。我没有通过任何考试
参考值。代码的第一部分似乎遵循
路过。但是扩展方法的第二部分,值
被保留,就好像它作为ByRef传递一样
有人能解释一下这背后的机制吗。谢谢
这是通过引用传递和传递引用对象(
class
)之间的区别。在GetProp
中,您不是在修改引用obj
,而是在修改obj
引用的MyObject
实例,这是通过引用传递和通过引用对象(类
)之间的区别。在GetProp
中,您不是在修改引用obj
,而是在修改由obj
引用的MyObject
实例,除非您使用ref
或out
关键字指定,否则所有参数都是按值发送的。按值传递参数意味着复制该值
但是,按值传递对象时,复制的不是对象,而是引用。这意味着您有两个对同一对象的引用,一个在obj
变量中,一个在o
参数中,但只有一个对象
当扩展方法访问对象时,它与方法外部的对象相同。以后使用
obj
变量访问属性时,使用o
参数对属性所做的任何更改都将可见。所有参数均按值发送,除非使用ref
或out
关键字指定。按值传递参数意味着复制该值
但是,按值传递对象时,复制的不是对象,而是引用。这意味着您有两个对同一对象的引用,一个在obj
变量中,一个在o
参数中,但只有一个对象
当扩展方法访问对象时,它与方法外部的对象相同。当您稍后使用
obj
变量访问属性时,使用o
参数对属性所做的任何更改都将可见。如果我理解您的问题,您会对sum
变量按值传递时为什么不更改感到困惑,但是当通过引用传递obj
时,obj.sum
属性确实保留其值。其他答案很好地解释了这一点
在您的问题中,您作为接收者按值传递一个参数,这有点混淆了您的问题。您的问题似乎是,“为什么当我正常传递时,它被视为按值传递,而当我作为接收者传递给扩展方法时,它是按引用传递的?”
啊。尝试为接收者分配一个新值,并查看呼叫站点发生的情况:
public static void GetProp(this int i, MyObject o)
{
o.sum = i;
i = 5000;
}
您会发现调用站点上的变量
test
不受此影响,因为接收器也通过值传递 如果我理解您的问题,您会感到困惑,为什么sum
变量在按值传递时没有更改,而obj.sum
属性在obj
按引用传递时保留其值。其他答案很好地解释了这一点
在您的问题中,您作为接收者按值传递一个参数,这有点混淆了您的问题。您的问题似乎是,“为什么当我正常传递时,它被视为按值传递,而当我作为接收者传递给扩展方法时,它是按引用传递的?”
啊。尝试为接收者分配一个新值,并查看呼叫站点发生的情况:
public static void GetProp(this int i, MyObject o)
{
o.sum = i;
i = 5000;
}
您会发现调用站点上的变量
test
不受此影响,因为接收器也通过值传递 您是否熟悉如何在扩展方法中使用ref
关键字?您是否熟悉如何在扩展方法中使用ref
关键字
public static void GetProp(this int i, MyObject o)
{
o.sum = i;
i = 5000;
}