0

I defined a public delegate and its static members(returning object type) in a separate class and am trying to invoke it from different winforms. These winforms would then check the type returned by the delegate member and then cast it appropriately. So far, so good. But, Visual Studio is complaining that my delegate type declared in each winform is never assigned to and its value will always be null.

The warning is:

Warning CS0649 Field 'AccountReplenish.transferDelegate' is never assigned to, and will always have its default value null ETTA in AccountReplenish.cs

Also, in AccountReplenish, how do I call GetData() of the delegate class? Here's my code:

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

And each of my winform would invoke it as below:

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

Any help is appreciated. NH

Edit: I made a few edits(see above) to the code above and it seems to be working ok.

SoftwareDveloper
  • 559
  • 1
  • 5
  • 18
  • 1
    Could you clarify exactly where the warning comes up? You've got `TransferObject` fields in two different classes, so it's hard to tell which is causing the problem. It would also help if you could reduce the code to *just* what's required to reproduce the problem, and then format it more readably. – Jon Skeet Dec 18 '19 at 16:22
  • The default constructor in class `AutoReplenishWindow ` does not initialize `transferDelegate`. You access static members through the type name `DelegateClass.GetData()`. You should probably rather use events. See: [What are the differences between delegates and events?](https://stackoverflow.com/questions/29155/what-are-the-differences-between-delegates-and-events). – Olivier Jacot-Descombes Dec 18 '19 at 16:43

1 Answers1

0

You should do it differently. Let's make an example. I changed your DelegateClass into a static Transmitter class, because that's what it does it transmits data from a sender to a receiver. It has a public event any receiver can subscribe to.

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

Now, let's create a receiver form that can display data it receives:

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

We also need a sender. It sends data entered in a textbox when a button is clicked:

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

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

The test program opens both windows

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

When you enter text in the sender form and click the button, the text is automatically displayed in the receiver form.

Note that it is not necessary to have a GetData() method. As the event handler private void Transmitter_DataReceived(object data) gets the data through the object data parameter.

A delegate is not a transfer object. According to Delegates (C# Programming Guide):

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

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188