user2640145
user2640145

Reputation: 37

Object instance from one class being changed from another class

I have a class called FrameSelector, which just stores a "path" to iframes on a web page. This class contains an instance of FramePath which is the actual path to the current frame.

I instantiate an Element which also contains a FramePath field, I assing the FramePath from FrameSelector to it, when I use FrameSelector.SelectDefaultContent() which essentially clears the FramePath, the Element.FramePath has 0 segments, it should not be changed.

I guess this is happening because Element.FramePath references FrameSelector.FramePath.

How can I overcome this?

 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();
    }
}

Upvotes: 1

Views: 563

Answers (2)

user2640145
user2640145

Reputation: 37

Solved by creating a Clone method.

public FramePath Clone()
    {
        FramePath result = new FramePath();

        result.XpathSegments = XpathSegments.GetRange(0, XpathSegments.Count);

        return result;
    }

Upvotes: 0

Jawad
Jawad

Reputation: 11364

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

When you assign the value to of FramePath to el.FramePath, you are essentially setting two pointers to frameSelector.FramePath. You are not duplicating or copying the object's value but assigning another variable to the same thing in memory.

When you call, frameSelector.SelectDefaultContent();, you clear the FramePath of frameSelector.. but since el.FramePath is also set to the same memory, el.FramePath is also cleared.

You can look into cloning or creating a Deep Copy (instead of shallow copy). This will prevent changes to other objects that you want to use to keep track of old values.

You can use the constructor, new FramePath(frameSelector.FramePath) to create a new object which will help in separating the references.

Upvotes: 1

Related Questions