C#:公共代表:从不同的类进行调用

C#: public Delegates: Invoke from different classes

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

警告是:

警告CS0649字段'AccountReplenish.transferDelegate'从未分配,并且AccountReplenish.cs中的默认值始终为空ETTA。

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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都会如下调用它:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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);
             }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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类,因为它就是将数据从发送方传输到接收方的方式。它有一个公共事件,任何接收者都可以订阅。

1
2
3
4
5
6
7
8
9
10
11
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.
    }
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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();
    }
}

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

1
2
3
4
5
6
7
8
9
10
11
12
public partial class SendDataForm : Form
{
    public SendDataForm()
    {
        InitializeComponent();
    }

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

测试程序会同时打开两个窗口

1
2
3
4
5
6
7
8
9
10
11
12
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参数获取数据时。

委托不是转移对象。根据代表(《 C#编程指南》):

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