[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 348
  • Last Modified:

delegate question

Trying to learn delegates in C#.


What is wrong with my syntax.

Compiler keeps complaining:

A field initializer cannot reference the nonstatic field, method, or property 'RigWatchClient.WITSRecord.BadType(string)'



======================

using System;
using System.Text.RegularExpressions;
using System.Collections;


namespace RigWatchClient
{

      public delegate string BadItemType(string b);

      public class WITSRecord
      {
            public BadItemType bitv = new BadItemType(BadType);

            public string BadType(string TypeWatchedFor)
            {
                  return TypeWatchedFor;
            }
      }
}
0
Tom Knowlton
Asked:
Tom Knowlton
  • 13
  • 11
1 Solution
 
TheAvengerCommented:
You should assign the value in the constructor:

using System;
using System.Text.RegularExpressions;
using System.Collections;


namespace RigWatchClient
{

     public delegate string BadItemType(string b);

     public class WITSRecord
     {
          public BadItemType bitv = null;

          public WITSRecord()
          {
                  this.bitv = new BadItemType(this.BadType);
          }

          public string BadType(string TypeWatchedFor)
          {
               return TypeWatchedFor;
          }
     }
}
0
 
Tom KnowltonWeb developerAuthor Commented:
TheAvenger:

You were correct  (thanks)  ....   but I do not understand WHY you were correct.   :)
0
 
Tom KnowltonWeb developerAuthor Commented:
Is the problem that the method BadType(  )   did not exist yet...or would not exist by that point?
0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
Tom KnowltonWeb developerAuthor Commented:
Also....if I could trouble you further......how do I wire-up to the BadItemType(  ) delegate as an event in code that uses an instance of WITSRecord?
0
 
TheAvengerCommented:
The problem is that before the constructor starts, the object this is not known. But you try to use it in the delegate constructor (which was executed before the default class constructor) and that's why it failed.

I didn't understand your question about the event. Can you paraphrase it?
0
 
Tom KnowltonWeb developerAuthor Commented:
Okay.

To rephrase my question.....I want to raise a custom event in one class and have it responded to another class.
0
 
TheAvengerCommented:
OK, this is best made like this:

public delegate void D (object sender, EventArgs e);
public class A
{
      private D _myEvent = null;
      public event D MyEvent
      {
            add {this._myEvent += value;}
            remove {this._myEvent -= value;}
      }

      public A ()
      {
            if (this._myEvent != null)
                  this._myEvent(this, EventArgs.Empty);
      }
}

public class B
{
      public void MyHandler (object sender, EventArgs e)
      {
            // Do something
      }
      public B()
      {
            A a = new A();
            a.MyEvent += new D (this.MyHandler);
      }
}

If you have any questions, don't hesitate to ask
0
 
Tom KnowltonWeb developerAuthor Commented:
TheAvenger:


Can you redo this in the form of a Windows Application (skeleton) and a Class1.cs file?
0
 
TheAvengerCommented:
Well, just replace the name of the class from A to Class1 for example. Which should be the second class?
0
 
Tom KnowltonWeb developerAuthor Commented:
Sorry....perhaps I am making this harder than it needs to be.

=================

Let's say this is class Helper:


public class Helper
{

    public string Name="";

   public void ChangeName( )
  {
         Name = "Fred";
  }
}


In my Windows Application I have a class called  Form1.

public class Form1
{
      Helper hlp = new Helper

      hlp.ChangeName(  )
}



Inside ChangeName.........when the Name data member is changed........I want raise an event that Form1 responds to.
0
 
TheAvengerCommented:
public delegate void MyDel (object sender, EventArgs e);

public class Helper
{

  private MyDel _nameChanged = null;
  public event MyDel NameChanged {
    add {this._nameChanged += value;}
    remove {this._nameChanged -= value;}
  }

    public string Name="";

   public void ChangeName( )
  {
         Name = "Fred";

         if (this._nameChanged != null)
             this._nameChanged (this, EventArgs.Empty);
  }
}
0
 
Tom KnowltonWeb developerAuthor Commented:
Okay......and then what does the code for Form1  (my skeleton C# Windows Form) look like?
0
 
Tom KnowltonWeb developerAuthor Commented:
I need like a System.Diagnostics.Debug.WriteLine( )   that shows the event being fired....or something.......
0
 
TheAvengerCommented:
probably something like:

public class Form1
{
      Helper hlp = new Helper
      hlp.NameChanged += new MyDel (this.OnNameChanged);

      hlp.ChangeName(  );

...
      private void OnNameChanged (object sender, EventArgs e)
      {
          // Do something
      }
}
0
 
TheAvengerCommented:
So, change Do something to:

System.Console.Out.WriteLine ("NameChanged fired")
0
 
Tom KnowltonWeb developerAuthor Commented:
FOR MY NOTES:



Here is the main form code:

using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;

namespace WindowsApplicationTestDelegate
{
      /// <summary>
      /// Summary description for Form1.
      /// </summary>
      public class Form1 : System.Windows.Forms.Form
      {
            /// <summary>
            /// Required designer variable.
            /// </summary>
            private System.ComponentModel.Container components = null;

            public Helper hlp = new Helper();

            

            public Form1()
            {
                  //
                  // Required for Windows Form Designer support
                  //
                  InitializeComponent();

                  //
                  // TODO: Add any constructor code after InitializeComponent call
                  //
                  hlp.NameChanged += new MyDel (this.OnNameChanged);      
                  hlp.ChangeName();
            }

            
            private void OnNameChanged (object sender, EventArgs e)
            {
                  // Do something
                  System.Diagnostics.Debug.WriteLine("it fired");
            }


            /// <summary>
            /// Clean up any resources being used.
            /// </summary>
            protected override void Dispose( bool disposing )
            {
                  if( disposing )
                  {
                        if (components != null)
                        {
                              components.Dispose();
                        }
                  }
                  base.Dispose( disposing );
            }

            #region Windows Form Designer generated code
            /// <summary>
            /// Required method for Designer support - do not modify
            /// the contents of this method with the code editor.
            /// </summary>
            private void InitializeComponent()
            {
                  this.components = new System.ComponentModel.Container();
                  this.Size = new System.Drawing.Size(300,300);
                  this.Text = "Form1";
            }
            #endregion

            /// <summary>
            /// The main entry point for the application.
            /// </summary>
            [STAThread]
            static void Main()
            {
                  Application.Run(new Form1());
            }
      }
}









======================================
======================================









Here is the Helper class code:





using System;

public delegate void MyDel (object sender, EventArgs e);

namespace WindowsApplicationTestDelegate
{
      public class Helper
      {

            private MyDel _nameChanged = null;
            public event MyDel NameChanged
            {
                  add {this._nameChanged += value;}
                  remove {this._nameChanged -= value;}
            }

            public string Name="";

            public void ChangeName( )
            {
                  Name = "Fred";

                  if (this._nameChanged != null)
                        this._nameChanged (this, EventArgs.Empty);
            }
      }
}
0
 
TheAvengerCommented:
So, it's OK now?
0
 
Tom KnowltonWeb developerAuthor Commented:
Thanks....I think I have it now.


One day I'll look back on this and wonder why it was so hard for me.


But for now....it is somewhat confusing.....



I wish I could tell you WHAT is confusing about it......hard to put my finger on it.
0
 
Tom KnowltonWeb developerAuthor Commented:
 public event MyDel NameChanged
          {
               add {this._nameChanged += value;}
               remove {this._nameChanged -= value;}
          }




what is add doing?


Is add necessary for event to work?
0
 
TheAvengerCommented:
Add is adding a new handler to the event; remove is removing an event handler. So actually add is executed when you write:

hlp.NameChanged += ....

and Remove is executed when you write:

hlp.NameChanged -= ....
0
 
TheAvengerCommented:
It's exactly like properties, where you have set and get (here they are add and remove)
0
 
Tom KnowltonWeb developerAuthor Commented:
Okay.


Do you know of any delegate tutorials online....that are very good....and explain delegates and events in very simple terms????


It helps me to get 2 or 3 descriptions of a concept...and one of them is bound to stick.  :)


Thanks for all of your help.
0
 
Tom KnowltonWeb developerAuthor Commented:
Here is my attempt to follow the flow of the delegate / event:


http://www.knowltonsoftware.com/junk/delegate_working_gif.gif
0
 
TheAvengerCommented:
It's exactly as you have drawn it
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

  • 13
  • 11
Tackle projects and never again get stuck behind a technical roadblock.
Join Now