Valuex
Valuex

Reputation: 126

C#: How to keep the global variable not changed when passed to a function?

I am developing an add-in for OneNote. In the sinppet below, a global variable AllPageXML is claimed first.
Then the very first time when a window is loaded, AllPageXML is initinized with a value.
After that, the value of AllPageXML is supposed to not be changed.
When the user input some keywords in a textbox, search in AllPageXML will be excuted.
And AllPageXML will be passed to an function FilterXml. After returnning, the value of AllPageXML has been changed.
How can I do to keep the value of AllPageXML not changed? Any comments will be appreciated.

    internal partial class NaviPages : LocalizableForm
    {
        public XElement AllPageXML;
        public NaviPages()
        {
            InitializeComponent();

        }
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            using var one = new OneNote();
            var AllPageXML = one.GetAllPages();
            //...//

        }
        
        private void tBoxKw_TextChanged(object sender, EventArgs e)
        {
            try
            {
                string strKeyWords = tBoxKw.Text.ToLower();
                FilteredPageXml = FilterXml(AllPageXML, strKeyWords);           
            }
            catch
            {
                MessageBox.Show("Failed to filter!");
            }
        }
         public XElement FilterXml(XElement inXML, string strKeyWords)
        {
            string strSecKw, strPageKw;
            XElement root = inXML;
            ///...///
            //delete empty notebook
            foreach (var child1 in root.Elements().Reverse())
            {
                if (!child1.HasElements) child1.Remove();
            }
            return root;
        }

    }

Also, I've tried to use the ICloneable class to clone the AllPageXML before using it.



namespace OneNoteAddIn
{
    internal partial class NaviPages : LocalizableForm
    {
        public NaviPages()
        {
            InitializeComponent();

        }
        public MyPages xml1;
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            using var one = new OneNote();
            xml1= new MyPages();
            xml1.AllPageXML= one.GetAllPages();   
        }


        public XElement FilterXml(XElement inXML, string strKeyWords)
        {
            XElement root = inXML; // xml2.AllPageXML;
            //delete empty notebook
            foreach (var child1 in root.Elements().Reverse())
            {
                if (!child1.HasElements) child1.Remove();
            }
            return root;
        }

             
        private void tBoxKw_TextChanged(object sender, EventArgs e)
        {
            XElement FilteredPageXml;
            MyPages xml2 = new MyPages();
            xml2 = (MyPages)xml1.Clone();
            XElement AllPageXML1 = xml2.AllPageXML;
            try
            {
                string strKeyWords = tBoxKw.Text.ToLower();
    
                    FilteredPageXml = FilterXml(AllPageXML1, strKeyWords);      
            }
            catch
            {
                MessageBox.Show("Failed to filter!");
            }
        }


    }
    class MyPages : ICloneable
    {
        public XElement AllPageXML;
        public object Clone()
        {
            return this.MemberwiseClone();
        }
    }

}

Upvotes: 0

Views: 77

Answers (1)

Blit
Blit

Reputation: 55

The line XElement root = inXML; does not create a new object, it only sets the reference of root to the same reference inXML uses. So any changes to root or inXML will change the same object in memory. You should instead clone the object (create a new one with the same values). This can be done in 2 places.

  1. In the FilterXml method.
  2. In tBoxKw_TextChanged before FilterXml is called and pass FilterXml the clone.

To clone an object you should create a new object (using new XElement()) and set the properties of that element to the values of properties of the object you wish to clone (AllPageXML). You could look into the ICloneable interface: https://learn.microsoft.com/en-us/dotnet/api/system.icloneable.clone?view=net-7.0

Upvotes: 2

Related Questions