C# 扩展方法的变量范围

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 {

我有一些有趣的东西,我想更深入地了解一下

我有一个扩展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

但是在上面的代码中,当我使用扩展名传递变量时 方法,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;
    }