重新初始化一个不工作的对象

本文关键字:一个 工作 对象 初始化 | 更新日期: 2023-09-27 18:27:51

我在将对象"重置"回某些默认值时遇到一些问题。

所以我有一个对象,叫做MPoint类型的点(我自己的类)。如果该点被使用超过一定次数,我希望将该点重置回其默认值。因此,我创建了一个名为CheckPointExpired的方法,如下所示。

问题是该方法被调用,如果点属性PointUsed大于MaxResuse,它会将点对象设置为null并创建一个新点。然而,当在RunPoint方法中调试我的代码时,我可以看到点对象的值没有改变。我不明白为什么?

据我所知,当我将点对象传递给CheckPointExpired方法时,它是作为引用传递的,所以对对象的任何更改都应该反映回RunPoint方法中吗?很明显我不明白什么。

  public MPoint RunPoint(MPoint point)
  {
      // first check if point has expired
      CheckPointExpired(point)
      // rest of my code
  }
  void CheckPointExpired(MPoint point)
  {
     if (point.PointUsed >= point.MaxResuse)
     {
        int lvl = point.Level;
        int maxLB = point.MaxLookBack;
        int maxReuse = point.MaxResuse;
        int order = point.Order;            
        point = null;
        point = new MPoint(maxReuse, maxLB, lvl, order);
     }
  }

重新初始化一个不工作的对象

您需要使用ref关键字传递点作为引用:

void CheckPointExpired(ref MPoint point)
{
    if (point.PointUsed >= point.MaxResuse)
    {
       int lvl = point.Level;
       int maxLB = point.MaxLookBack;
       int maxReuse = point.MaxResuse;
       int order = point.Order;            
       point = null;
       point = new MPoint(maxReuse, maxLB, lvl, order);
   }
}
CheckPointExpired(ref point);

否则,您只能更改点的字段或属性,它们将在原始对象上可见,但赋值不会更改传递的参数的引用。即使类是引用类型,当您不使用ref时,该参数实际上是原始引用的副本。例如:

string foo = "Foo";
string bar = foo;

这里的赋值bar = foo将foo的引用复制到bar。因此,有两个不同的引用指向相同的位置。每当您用另一个值初始化条形图时,它只会丢弃旧的引用,不会影响foo:

bar = "bar";

您忘记在函数中引用它来更改值。您通过值/只读方式将其传递给函数。ref关键字仅供参考,表示通过其地址传递对象,允许您在函数内部编辑和/或更改对象。

void CheckPointExpired(ref MPoint point)
  {
     if (point.PointUsed >= point.MaxResuse)
     {
        int lvl = point.Level;
        int maxLB = point.MaxLookBack;
        int maxReuse = point.MaxResuse;
        int order = point.Order;            
        point = null;
        point = new MPoint(maxReuse, maxLB, lvl, order);
     }
  }

您还需要将地址传递给函数,否则函数将无法从对象中读取地址。

public MPoint RunPoint(MPoint point)
  {
      // first check if point has expired
      CheckPointExpired(ref point)
      // rest of my code
  }