C#:如何保持全局变量传递给函数时不改变?

问题描述 投票:0回答:1

我正在为 OneNote 开发一个插件。 在下面的 sinppet 中,首先声明了一个全局变量

AllPageXML

然后,第一次加载窗口时,
AllPageXML
会被初始化为一个值。
之后,
AllPageXML
的值应该不会改变。
当用户在文本框中输入一些关键字时,将执行
AllPageXML
中的搜索。
并且
AllPageXML
将被传递给函数
FilterXml
。返回后,
AllPageXML
的值已经改变了。
如何才能保持
AllPageXML
的值不改变?任何意见将不胜感激。

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

    }

另外,我在使用之前尝试使用

ICloneable
类来克隆
AllPageXML



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

}

c# pass-by-reference pass-by-value onenote
1个回答
2
投票

XElement root = inXML;
不会创建新对象,它只是将
root
的引用设置为
inXML
使用的相同引用。因此,对
root
inXML
的任何更改都会更改内存中的同一对象。您应该克隆该对象(创建一个具有相同值的新对象)。这可以在 2 个地方完成。

  1. FilterXml
    方法中。
  2. tBoxKw_TextChanged
    之前调用
    FilterXml
    并传递
    FilterXml
    克隆。

要克隆对象,您应该创建一个新对象(使用

new XElement()
)并将该元素的属性设置为您要克隆的对象的属性值 (
AllPageXML
)。您可以查看
ICloneable
界面:https://learn.microsoft.com/en-us/dotnet/api/system.icloneable.clone?view=net-7.0

© www.soinside.com 2019 - 2024. All rights reserved.