C#:public 委托:从不同的地方调用 类

C#: public Delegates: Invoke from different classes

我在单独的 class 中定义了一个 public 委托及其静态成员(返回对象类型),并试图从不同的 winform 调用它。然后,这些 winforms 将检查委托成员返回的类型,然后适当地转换它。到目前为止,一切都很好。但是,Visual Studio 抱怨我在每个 winform 中声明的委托类型从未分配给它,它的值将始终为 null。

警告是:

警告 CS0649 字段 'AccountReplenish.transferDelegate' 从未分配给,并且在 AccountReplenish.cs

中始终具有默认值 null ETTA

此外,在 AccountReplenish 中,如何调用委托 class 的 GetData()? 这是我的代码:

namespace ETTA.Classes
{
    public class DelegateClass
    {

        public delegate void TransferDelegate(object data);
        public TransferDelegate transferDelegate;
        private static object _receivedOutput = new object();
        public DelegateClass()
        {
            this.transferDelegate += new ETTA.Classes.DelegateClass.TransferDelegate(ReceiveOutput);
        }
        public static void ReceiveOutput(object data)
        {
            _receivedOutput = data;
        }
        public static object GetData()
        {
            return _receivedOutput;
        }
}

我的每个 winform 都会调用它如下:

public partial class AccoutnReplenish : Form
{
    private ETTA.Classes.DelegateClass.TransferDelegate transferObject;
    private object _receivedOutput = new object();

    public AccoutnReplenish()
    {
        this.transferObject= new Classes.DelegateClass.TransferDelegate (ETTA.Classes.DelegateClass.ReceiveOutput);
    }

    private void button_click(object sender, EventArgs e)
    {
      AutoReplenishWindow _progressWindow = new AutoReplenishWindow(transferObject);

      DialogResult dr = _progressWindow.ShowDialog(this);

      if (dr == System.Windows.Forms.DialogResult.OK )
         this._receivedOutput = ETTA.Classes.DelegateClass.GetData();
         if (this._receivedOutput != null && (this._receivedOutput.GetType() == typeof(string)))
             {
                string _s = (string)this._receivedOutput;
                MessageBox.Show("Result: " + _s);
             }
    }
}

public partial class AutoReplenishWindow : Form
    {
        private ETTA.Classes.DelegateClass.TransferDelegate transferObject;

        public AutoReplenishWindow()
        {
            InitializeComponent();
        }
        public AutoReplenishWindow(ETTA.Classes.DelegateClass.TransferDelegate del)
        {
            InitializeComponent();
            transferObject = del;
        }


        private async void AutoReplenishWindow_Shown(object sender, EventArgs e)
        {
            int arg1 = 12;
            string _result = await dbUtils.CallFunction(arg1);

            if (_result  != null && transferObject!= null)
            {                
                transferObject.Invoke(_result );                    
                this.Close();
            }
        }
    }

感谢任何帮助。 NH

编辑:我对上面的代码进行了一些编辑(见上文),它似乎工作正常。

你应该换一种方式。让我们举个例子。我将您的 DelegateClass 更改为静态 Transmitter class,因为它就是这样做的,它将数据从发送方传输到接收方。它有一个任何接收者都可以订阅的 public 事件。

public delegate void DataReceivedEventHandler(object data);

public static class Transmitter
{
    public static event DataReceivedEventHandler DataReceived;

    public static void TransmitData(object data)
    {
        DataReceived?.Invoke(data); // Raise the event.
    }
}

现在,让我们创建一个可以显示它接收到的数据的接收器表单:

public partial class ReceiveDataForm : Form
{
    public ReceiveDataForm()
    {
        InitializeComponent();

        // Subscribe the event
        Transmitter.DataReceived += Transmitter_DataReceived;
    }

    private void Transmitter_DataReceived(object data)
    {
        // Display data.
        textBox1.Text = data.ToString();
    }
}

我们还需要一个发件人。单击按钮时,它会发送在文本框中输入的数据:

public partial class SendDataForm : Form
{
    public SendDataForm()
    {
        InitializeComponent();
    }

    private void SendDataButton_Click(object sender, EventArgs e)
    {
        Transmitter.TransmitData(dataTextBox.Text);
    }
}

测试程序同时打开windows

static class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        var sender = new SendDataForm();
        sender.Show();
        Application.Run(new ReceiveDataForm());
    }
}

当您在发件人表单中输入文本并单击按钮时,文本会自动显示在收件人表单中。

请注意,没有必要使用 GetData() 方法。由于事件处理程序 private void Transmitter_DataReceived(object data) 通过 object data 参数获取数据。

委托不是传输对象。根据 Delegates (C# Programming Guide):

A delegate is a type that represents references to methods with a particular parameter list and return type.