【问题标题】:How to save a ref variable for later use?如何保存 ref 变量以供以后使用?
【发布时间】:2011-11-07 09:03:51
【问题描述】:

所以这行得通..

public MyClass(ref Apple apple)
{
    apple = new Apple("Macintosh"); // Works fine
}

但是有可能做这样的事情吗?

private Apple myApple;

public MyClass(ref Apple apple)
{
    myApple = apple;
}

public void ModifyApple()
{
    myApple = new Apple("Macintosh"); // does not change the input variable like the first example did
}

当 ref 变量被复制到成员变量 myApple 时,它似乎失去了它的“ref-ness”并且重新分配它不再改变输入变量。有没有办法解决这个问题?

【问题讨论】:

    标签: c# reference ref


    【解决方案1】:

    ref-ness 是函数参数和传递给函数的参数的属性。一般来说,它不是变量(甚至字段)的属性。

    确实,你在那里尝试的东西从一开始就注定要失败。

    【讨论】:

      【解决方案2】:

      不是真的,不。到下次调用您的代码时,用作方法参数的原始变量甚至可能不再存在:

      void Foo()
      {
          MyClass x = Bar();
          x.ModifyApple();
      }
      
      MyClass Bar()
      {
          Apple apple = new Apple();
          return new MyClass(ref apple);
      }
      

      这里,apple 是一个 本地 变量,在我们调用 ModifyApple 时将被弹出的堆栈帧中。

      您确定需要修改原始调用者的变量,而不仅仅是更改对象本身吗?

      排序的一种方法是使用包装器类型来开始:

      public class MutableWrapper<T>
      {
          public T Value { get; set; }
      }
      

      然后传入MutableWrapper&lt;Apple&gt;,并将其存储在您的班级中。然后在ModifyApple你可以写:

      wrapper.Value = new Apple();
      

      这不会改变调用者的变量,但是下次调用者查看Value 属性时,他们会看到你的新苹果。

      说实话,这种事情往往会导致代码难以维护,甚至ref 的可读性也不是很好。如果您能从大局说明您想要实现的目标,我们或许可以提出更好的整体方法。

      【讨论】:

      • 嗯,这就是我想要得到的工作:pastebin.com/v4pNa1um 我不能将 activeLayer 作为参考传递给 Undo 和 Redo 的原因是因为我不知道那时它是什么。有什么想法吗?
      • @Joey:这并没有真正展示大局——它只是展示了试图更新一些变量。例如,也许您想要一堆撤消层?
      • 我的程序中已经有一个撤消和重做堆栈。基本上,我的程序中的任何可撤消或可重做的操作都会操纵平铺层。在对切片图层进行更改之前,会将新的编辑推送到堆栈中,并在进行任何更改之前保存切片图层。然后,如果用户曾经使用过撤消或重做,它应该将图层恢复到其保存的撤消或重做状态。
      • @Joey:恐怕这并不能帮助我理解为什么你觉得你需要这里的“参考”。但是,无论哪种方式,恐怕它都不可用......
      • 是否有任何理由将 Value 设为属性而不是字段?字段可以与联锁方法等一起使用,而属性则不能。
      【解决方案3】:

      不,没有。 myApple 是一个包含对 Apple 的引用的字段;然而,参数apple 实际上是对苹果的引用。当您将apple 分配给myApple 时,您取消引用参数的值。除此之外,它们是独立且不同的。

      所以不:这是不可能的。

      可能有类似的东西:

      public class AppleWrapper {
          public Apple Value {get;set;}
      }
      

      现在;如果您存储AppleWrapper,任何数量的调用者都可以访问并更改.Value

      【讨论】:

        【解决方案4】:

        为什么不让 ModifyApple 返回修改后的 Apple 实例?

        public Apple ModifyApple()
        {
            myApple = new Apple("Macintosh"); // does not change the input variable like the first example did
            return myApple;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2012-02-29
          • 2021-10-11
          • 1970-01-01
          • 1970-01-01
          • 2011-09-05
          • 1970-01-01
          • 1970-01-01
          • 2020-09-15
          相关资源
          最近更新 更多