【问题标题】:Variable Scope For an Extension Method扩展方法的变量范围
【发布时间】:2015-07-31 17:20:14
【问题描述】:

我有一些有趣的事情想深入了解一下。

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

谁能解释一下这背后的机制。谢谢

【问题讨论】:

标签: c# scope extension-methods


【解决方案1】:

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

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

当扩展方法访问对象时,它与方法外的对象是同一个对象。使用o 参数对属性所做的任何更改都将在您稍后使用obj 变量访问它时可见。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      在您的问题中,您通过值传递参数作为接收者,这使您的问题有点混乱。您的问题似乎是,“为什么当我正常传递时,它被视为按值处理,但当我作为接收器传递给扩展方法时,它是按引用?”

      啊。尝试为接收者分配一个新值,看看调用站点会发生什么:

          public static void GetProp(this int i, MyObject o)
          {
              o.sum = i;
              i = 5000;
          }
      

      你会发现调用处的变量test不受此影响,因为接收者也是传值的!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-08-21
        • 2016-05-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多