【问题标题】:C# reference issue in another form另一种形式的 C# 参考问题
【发布时间】:2020-12-15 10:31:29
【问题描述】:

我有一个小问题想在脑海中解决。 我有一个整数,我每秒递增一次。我将此整数作为对另一个表单的引用传递并希望显示它。因此,通过单击按钮,我实例化了第二种形式,并将引用指向我第二种形式中的本地整数。

我在第二个表单上每秒显示一次值,但它只会在我重新创建一个新的 form2 实例时更新。

public partial class Form1 : Form
    {
        private static int test = 0;
        public Form1()
        {
            InitializeComponent();
            TestClass.Init();

            Timer t = new Timer();
            t.Interval = 1000;
            t.Tick += new EventHandler(tick);
            t.Start();
        }

        private void tick(object sender, EventArgs e)
        {
            ++test;
        }

        public delegate void TestEventHandler(ref int test);
        public static event TestEventHandler TestEvent;

        internal static void TestEventRaised(ref int test)
        {
            TestEvent?.Invoke(ref test);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            TestEventRaised(ref test);
        }
    }
    public static class TestClass
    {
        private static Form2 form2;
        public static void Init()
        {
            Form1.TestEvent += new Form1.TestEventHandler(Event);
        }

        private static void Event(ref int test)
        {
            if (form2 != null)
            {
                form2.Close();
                form2 = null;
            }
            form2 = new Form2(ref test);
            form2.ShowDialog();
        }
    }
    public partial class Form2 : Form
    {
        int _test = 0;
        public Form2(ref int test)
        {
            InitializeComponent();
            _test = test;

            Timer t = new Timer();
            t.Interval = 1000;
            t.Tick += new EventHandler(tick);
            t.Start();
        }

        private void tick(object sender, EventArgs e)
        {
            label1.Text = _test.ToString();
        }
    }

我不明白为什么这不起作用,因为当调用 form2 的构造函数时,我将 _test 链接到测试。 TestClass 在我的“真实”代码中有它的目的,即链接作为 DLL 的 Form1 和 Form2。

你知道为什么这不起作用吗?

谢谢!

【问题讨论】:

  • 忠告:将数据与演示文稿分开。将该整数和计时器移动到一个单独管理的类中,该类将执行增量或其他操作。你的生活会简单得多。
  • @TanveerBadar 它在我的“真实”代码中。不过,为了简单起见,不在这个问题中添加数百行代码,我将它们全部合并在一起。

标签: c# events ref


【解决方案1】:

调用form2的构造函数时,我将_test链接到test

不,你没有。

Form2构造函数中的这行代码:

_test = test;

... 将test 参数的当前值复制到_test 字段。这就是它所做的一切。在这种情况下,您的 test 参数是 ref 参数这一事实无关紧要,因为您永远不会在构造函数中写入它(也没有在另一个线程中更新该参数,这将是可见的)。

我建议您不要使用两个单独的 int 字段,而是使用 Counter 类:

public class Counter
{
    // TODO: Potentially thread safety, or consider making Value publicly read-only
    // with an "Increment" method
    public int Value { get; set; }
}

那么Form1Form2 都可以引用同一个Counterobject,此时该对象的content 将发生变化从两种形式都可见。 (我还建议避免使用静态字段。)

【讨论】:

  • 我喜欢这个我已经在我工作的其他几个地方使用过的想法。但是,这样做的缺点是创建一个新的依赖项,其中包含 3 行代码,仅用于此用途。另一种解决方案是将此 Counter 类添加到 Form1 或 Form2 依赖项之一中,另一个调用它,但它会创建我希望避免的相互依赖关系以保持整个可维护性。
  • 有没有办法使用 ref 保持链接,例如 C++ 中的指针?
  • @Nicola:不,没有。 int 字段将始终独立于其他字段。在 C# 的未来版本中,您可能在 ref struct 中有一个 ref 字段,但我不认为现在是这种情况,而且考虑到表单是类,它无论如何都对您没有帮助。您需要一个引用类型,以便两个表单可以引用相同的数据。如果您不关心任何封装,您可以使这个通用 - 一个 Wrapper<T> 类,它只有一个简单的 public T Value { get; set; }。如果你真的不想要你自己的类型,或者使用单元素数组。
  • 感谢您的回复。我设法通过用整数数组(大小 = 1)替换整数来使其工作。我想 _test = test 在这种情况下只会指向正确的数据。
  • @Nicola:是的,因为数组总是引用类型——但我强烈鼓励你引入一个新类。当然,这是一个依赖项——但它比单元素数组 IMO 要少得多。
猜你喜欢
  • 2014-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多