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

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

提问人:Valuex 提问时间:6/6/2023 最后编辑:Valuex 更新时间:6/6/2023 访问量:74

问:

我正在为 OneNote 开发加载项。 在下面的 sinppet 中,首先声明了一个全局变量。
然后,在第一次加载窗口时,将使用一个值启动。
之后,的值应该不会改变。
当用户在文本框中输入一些关键字时,将执行搜索。
并将传递给一个函数。返回后,值已更改。
我怎样才能保持值不变?任何意见将不胜感激。
AllPageXMLAllPageXMLAllPageXMLAllPageXMLAllPageXMLFilterXmlAllPageXMLAllPageXML

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

    }

另外,在使用它之前,我尝试使用该类来克隆它。ICloneableAllPageXML



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# 按引用 传递 onenote

评论

1赞 Mrinal Kamboj 6/6/2023
要么将变量标记为 const,在编译时将其烘焙,要么将其标记为只读,我猜可以在构造函数中更改一次,而不是进一步更改,任何更改尝试都会导致编译或运行时出错。一些参考资料 exceptionnotfound.net/...
1赞 wohlstad 6/6/2023
由于正在修改对象,因此您可以向其传递成员的克隆(或者在对它进行操作之前更改为克隆)。FilterXmlinXMLAllPageXMLFilterXmlinXML
0赞 Valuex 6/6/2023
这里仍然没有太多运气,即使我试图克隆一个。

答:

2赞 Blit 6/6/2023 #1

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

  1. 在方法中。FilterXml
  2. in before 被调用并传递克隆。tBoxKw_TextChangedFilterXmlFilterXml

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

评论

0赞 Valuex 6/7/2023
你能帮忙检查我上面发布的第二个片段吗?它仍然不起作用。如果能举出任何直接的例子,将不胜感激。