调用多种形式的方法时,类变量会被重置

本文关键字:类变量 多种形式 方法 调用 | 更新日期: 2023-09-27 18:13:09

更新以反映到我自己的源

我正在用c#构建我的第一个winform应用程序,我正在努力找出构建类的最佳实践,以便在表单中使用它们时能够顺利工作。我有几个例子,我会尽力解释。

当在类中处理get/set变量时,最佳实践应该是这样的:

JobMove.cs

public class JobMove
{
    private List<string> jobNames { get; set; }
    public string Scanner;
    public JobMove()
    {
        this.Scanner = Properties.Settings.Default.Scanner;
    }
    public void ListSelected(ListBox lbx)
    {
        foreach (string jName in this.jobNames)
        {
            lbx.Items.Add(jName);
        }
    }
    public static List<string> GetCheckedJobs(ListView lw)
    {
        int countChecked = lw.CheckedItems.Count;
        int itemCount = 0;
        List<string> jList = new List<string>();
        foreach (ListViewItem item in lw.CheckedItems)
        {
            JobInfo jobInfo = Job.Find(Convert.ToInt32(lw.Items[item.Index].SubItems[1].Text));
            jList.Add(jobInfo.Name);
            itemCount++;
        }
        return jList;
    }
}

我的问题是,当我把它和我的表格结合起来,并称之为时,我会尝试做这样的事情:

MyForm1.cs

public partial class MyForm1 : Form
{
    private void btnMoveJobs_Click(object sender, EventArgs e)
    {
        Properties.Settings.Default.Scanner = cbxScanners.SelectedItem.ToString();
        JobMove moveJobs = new JobMove();
        frmMoveJobs FrmMoveJobs = new frmMoveJobs();
        FrmMoveJobs.ShowDialog();
    }
}

MyForm2.cs

public partial class frmMoveJobs : Form
{
    public frmMoveJobs()
    {
        InitializeComponent();
        JobMove moveJobs = new JobMove();
        lblFrom.Text = moveJobs.Scanner;
        moveJobs.ListSelected(lbxJobsToMove);
        cbxMjScanners.DataSource = System.Enum.GetValues(typeof(Scanners));
    }
}

但是,当我在MyForm2中调用MyClass并且我想调用DoSomethingElse方法时,myString将重置为null值。这对我来说很有道理,但我该如何解决这个问题呢?

我试图弄清楚在这里使用什么来更容易地解决代码中的这些缺陷,但我的知识太弱,无法实现一个简单的解决方案。我知道我可以把这个变量存储在Settings.Settings中作为一个例子,但对我来说,对于这样一个简单的任务来说,这似乎是一个真正的过载。

我可能只需要一个正确的方向,就可以正确地判断在这种情况下该怎么做。

调用多种形式的方法时,类变量会被重置

如果您执行MyClass myClass = new MyClass();,那么实际上-值是独立且不相关的。如果要共享MyClass实例,则在表单之间传递MyClass实例。也许:

using(var form2 = new Form2()) {
    form2.SensibleName = existingMyClassInstance;
    form2.ShowDialog();
}

(注意上面的using btw;使用ShowDialog()时,您的工作是确保表单已处理;只有在使用Show()时才会自动处理(

首先,它们是属性,而不是变量(变量是底层数据源(。

其次,get/set访问器的全部意义在于,您可以在不需要辅助方法的情况下获取和设置值。

第三,关于你的问题,你正在以每种形式创建一个新的类实例(由new关键字暗示(,属性的值将是它在实例构造时初始化的值(或不初始化(,即属性的值在同一类型的不同实例之间不共享。

想想钥匙的模具:我可以从"蓝图"中获得钥匙切割的多个实例,但一个人所遭受的任何损坏都不会反映在其他实例中——从这个意义上说,它们是独一无二的。

如果您希望两个表单都访问该类型的同一实例,那么您需要将该实例存储在代码中双方都可以访问的某个位置。

几个选项:

  1. 在form2的构造函数中传入MyClass的实例。

  2. MyClass设为Form1Form2的静态属性,并通过其他表单上的属性访问它

  3. 使MyClass为静态(不推荐(

如果要在MyForm2内部使用在MyForm1中创建的MyClass实例,则需要将其提供给MyForm2

像这样的东西会起作用:

public partial class MyForm2 : Form
{
    public MyForm2(MyClass given)
    {
        InitializeComponent();
        given.DoSomethingElse();
    }
}

简单解决方案:

private static string myString { get; set; } 

原因:因为在初始化Form2时再次初始化该类,它将创建一个新的类。使用"static"关键字可以创建一个在该类的所有实例中都相同的属性。

但是:在继续之前,请先读一些书,这将是这个问题的解决方案,但也是许多其他问题的根源。试着先理解C#和Forms,然后(或与阅读/学习一起(开始编码!

这是因为每个表单都有一个新对象"MyClass"。

要实现您想要做的事情,请使用静态属性。。。它不会被初始化,并为MyClass的每个对象返回相同的值看起来像这个

public class MyClass {
   public static string myString { get; set; }
   public void ChangeMyString(string newString)
   {
       myString = newString;
   }
   public void DoSomethingElse()
   {
       MessageBox.Show(myString);
   }
}