扩展方法的可变范围

时间:2015-07-31 17:20:15

标签: 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 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);
  

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

有人可以解释这背后的机制。感谢

3 个答案:

答案 0 :(得分:3)

所有参数均按值发送,除非您使用refout关键字指定它们。按值传递参数意味着复制该值。

但是,当您按值传递对象时,它不是复制的对象,而是复制的引用。这意味着您有两个对同一对象的引用,一个在obj变量中,另一个在o参数中,但只有一个对象。

当扩展方法访问对象时,它与方法外部的对象相同。当您稍后使用o变量访问该属性时,使用obj参数对该属性所做的任何更改都将显示。

答案 1 :(得分:2)

这是传递引用和传递引用对象(class)之间的区别。在GetProp中,您无法修改引用obj,而是修改MyObject引用的obj实例。

答案 2 :(得分:0)

如果我理解您的问题,您会感到困惑,为什么sum变量在按值传递时没有更改,但是obj.sum属性在{{1}时确实保留了其值}通过引用传递。其他答案很好地解释了这一点。

在您的问题中,您通过值作为接收者传递了一个参数,这使您的问题有些困惑。您的问题似乎是,“为什么当我正常通过时,将其视为按值,但是当我将其作为接收器传递给扩展方法时,将其作为按引用吗?”

啊。尝试为接收方分配一个新值,看看呼叫现场会发生什么:

obj

您会发现呼叫站点的变量 public static void GetProp(this int i, MyObject o) { o.sum = i; i = 5000; } 不受此影响,因为通过值传递了接收者!

相关问题