【问题标题】:Object instance from one class being changed from another class一个类的对象实例从另一个类更改
【发布时间】:2020-02-12 01:39:54
【问题描述】:

我有一个名为 FrameSelector 的类,它只在网页上存储 iframes 的“路径”。此类包含 FramePath 的实例,它是当前帧的实际路径。

我实例化一个 Element 它还包含一个 FramePath 字段,我将 FramePath 从 FrameSelector 分配给它,当我使用基本上清除 FramePath 的 FrameSelector.SelectDefaultContent() 时,Element.FramePath 有 0段,不应更改。

我猜这是因为 Element.FramePath 引用了 FrameSelector.FramePath。

我该如何克服这个问题?

 public class Program   
{
    public static void Run()
    {
        FrameSelector frameSelector = new FrameSelector();

        frameSelector.SelectFrame(0);

        Element el = new Element();
        el.FramePath = frameSelector.FramePath;

        Console.WriteLine(el.FramePath.Segments.Count); // Outputs 1

        frameSelector.SelectDefaultContent(); // Resets frameSelector.FramePath

        Console.WriteLine(el.FramePath.Segments.Count); // Outputs 0? Why? el.FramePath should not have anything to do with frameSelector.FramePath?
        Console.ReadLine();
    }
}

class Element
{
    public FramePath FramePath;
}

class FrameSelector
{
    public FramePath FramePath;

    public FrameSelector()
    {
        FramePath = new FramePath();
    }

    public void SelectFrame(int id)
    {
        FramePath.AddSegment($"(//iframe)[{id + 1}]");
    }

    public void SelectDefaultContent()
    {
        FramePath.Clear();
    }
}

class FramePath
{
    public List<string> Segments { get; private set; }

    public FramePath()
    {
        Segments = new List<string>();
    }

    public void AddSegment(string segment)
    {
        Segments.Add(segment);
    }

    public void RemoveLastSegment()
    {
        Segments.RemoveAt(Segments.Count - 1);
    }

    public void Clear()
    {
        Segments.Clear();
    }
}

【问题讨论】:

  • "我猜这是因为 Element.FramePath 引用了 FrameSelector.FramePath。" - 是的

标签: c# object reference instance


【解决方案1】:
Element el = new Element();
el.FramePath = frameSelector.FramePath;`

当您将 FramePath 的值分配给 el.FramePath 时,您实际上是在设置两个指向 frameSelector.FramePath 的指针。您不是在复制或复制对象的值,而是将另一个变量分配给内存中的同一事物。

当你调用frameSelector.SelectDefaultContent();时,你清除了frameSelector的FramePath..但是由于el.FramePath也被设置为相同的内存,el.FramePath也被清除了。

您可以研究克隆或创建深层副本(而不是浅层副本)。这将防止更改您想要用来跟踪旧值的其他对象。

您可以使用构造函数new FramePath(frameSelector.FramePath) 创建一个新对象,这将有助于分离引用。

【讨论】:

    【解决方案2】:

    通过创建Clone方法解决。

    public FramePath Clone()
        {
            FramePath result = new FramePath();
    
            result.XpathSegments = XpathSegments.GetRange(0, XpathSegments.Count);
    
            return result;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-11-19
      • 2015-02-13
      • 1970-01-01
      • 1970-01-01
      • 2022-10-25
      • 1970-01-01
      • 2016-08-25
      • 1970-01-01
      相关资源
      最近更新 更多