locked
Why delegates are declared outside the class? RRS feed

  • Question

  • I'm curious on why this delegate needs to be declared outside the class, I also want to know why/what situations should I declare variables/types outside a class?

     //Create a delegate and name it MessageHandler
      public delegate void MessageHandler(string messageText);
      
      public class Connection
      {
        //Create an event and use MessageHandler as the delegate type
        //When this event is raised the MessageHandler delegate will use the specified method assigned in the main
        //see Main() con.MessageArrived += new MessageHandler(dis.DisplayMessage)
        //it means that MessageHandler will do the codes inside dis.DisplayMessage()
        public event MessageHandler MessageArrived;
        
        
        private Timer pollTimer;
        
    
        public Connection()
        {
          pollTimer = new Timer(100);
          
          //pass the codes of CheckForMessage inside pollTimer.Elapsed
          //CheckForMessage will be place inside an ElapsedEventHandler
          //the object below is an event so a new ElapsedEventHandler with the metohd CheckForMessage will be done once pollTimer.Elapsed occurs
          pollTimer.Elapsed += new ElapsedEventHandler(CheckForMessage);
    
        }
    
        public void Connect()
        {
          pollTimer.Start();
        }
    
        public void Disconnect()
        {
          pollTimer.Stop();
        }
    
        private static Random random = new Random();
    
        //object source is the object that raised the event = pollTimer.Elapsed
        //the codes inside this function will be passed to DisplayMessage() in the Display class
        private void CheckForMessage(object source, ElapsedEventArgs e)
        {
          Console.WriteLine("Checking for new messages.");
          
          //MessageArrived is not since => in main() con.MessageArrived += new MessageHandler(dis.DisplayMessage);
          if ((random.Next(9) == 0) && (MessageArrived != null))
          {
            //the string inside MessageArrived will be passed on to DisplayMessage() of Display class
            //the string ("Hello Mum!") is passed to DisplayMessage because the method accepts a string a parameter
            //ex. delagate string DelegateInstance(string a) => this will be passed to the method that it was delegated to and the codes inside that method will be executed 
            //delegate MessageHandler woud now do the method DisplayMessage() //check Main() con.MessageArrived += MessageHandler(dis.DisplayMessage)
            //MessageArrived("string message here") because it uses the delegate type MessageHandler which has the parameter MessageHandler(string s) ;
            MessageArrived("Hello Mum!");
          }
    
          else if (MessageArrived == null)
          {
            Console.WriteLine("wow");
          }
        }
    
      }
    }

    Your answers would be of great help because it will help me learn more about C#/Programming. Thank you! :D


    Randel Ramirez
    Tuesday, June 21, 2011 4:47 PM

Answers

  • "I'm curious on why this delegate needs to be declared outside the class, I also want to know why/what situations should I declare variables/types outside a class?"

     

    The delegate does not have to be specified outside of the class.  However, if you're creating an event, it typically makes sense to declare the delegate outside of the class since it will be used by other types, outside of the class.  That being said, you can just as easily declare it inside the class - but other types will have to fully-qualify it with the class name to use it.

     

    For example, in your above code, this is perfectly legal:

    class Test
    {
      // Delegate declared in class
      public delegate void MessageHandler(string messageText);
    
      public event MessageHandler MessageArrived;
    }
    


    However, if something else wants to refer to it, you'd have to do so by using "Test.MessageHandler" instead of just "MessageHandler".

     

    That being said, if you're using delegates to implement an event, I'd strongly recommend always using the EventHandler delegate or EventHandler<T>.  In your case, I'd rewrite this as:

    public class MessageEventArgs : EventArgs
    {
      public MessageEventArgs(string messageText)
      {
        this.MessageText = messageText;
      }
    
      public string MessageText { get; private set; }
    }
    
    public class Connection
    {
      public event EventHandler<MessageEventArgs> MessageArrived;
    
      // .......Other code.........
    
      private void CheckForMessage(object source, ElapsedEventArgs e)
      {
        Console.WriteLine("Checking for new messages.");
    
        // This pattern of using a "handler" is safer when multi-threading, which is going to happen with your timer
        var handler = this.MessageArrived; 
        if ((random.Next(9) == 0) && (handler != null))
        {
          handler(this, new MessageEventArgs("Hello Mum!"));
        }
      }
    
      // .......Other code.........
    
    


    This provides more consistency with the framework, as well as a bit of extra thread safety (in the code that raises the event).

     


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    Tuesday, June 21, 2011 5:16 PM

All replies

  • "I'm curious on why this delegate needs to be declared outside the class, I also want to know why/what situations should I declare variables/types outside a class?"

     

    The delegate does not have to be specified outside of the class.  However, if you're creating an event, it typically makes sense to declare the delegate outside of the class since it will be used by other types, outside of the class.  That being said, you can just as easily declare it inside the class - but other types will have to fully-qualify it with the class name to use it.

     

    For example, in your above code, this is perfectly legal:

    class Test
    {
      // Delegate declared in class
      public delegate void MessageHandler(string messageText);
    
      public event MessageHandler MessageArrived;
    }
    


    However, if something else wants to refer to it, you'd have to do so by using "Test.MessageHandler" instead of just "MessageHandler".

     

    That being said, if you're using delegates to implement an event, I'd strongly recommend always using the EventHandler delegate or EventHandler<T>.  In your case, I'd rewrite this as:

    public class MessageEventArgs : EventArgs
    {
      public MessageEventArgs(string messageText)
      {
        this.MessageText = messageText;
      }
    
      public string MessageText { get; private set; }
    }
    
    public class Connection
    {
      public event EventHandler<MessageEventArgs> MessageArrived;
    
      // .......Other code.........
    
      private void CheckForMessage(object source, ElapsedEventArgs e)
      {
        Console.WriteLine("Checking for new messages.");
    
        // This pattern of using a "handler" is safer when multi-threading, which is going to happen with your timer
        var handler = this.MessageArrived; 
        if ((random.Next(9) == 0) && (handler != null))
        {
          handler(this, new MessageEventArgs("Hello Mum!"));
        }
      }
    
      // .......Other code.........
    
    


    This provides more consistency with the framework, as well as a bit of extra thread safety (in the code that raises the event).

     


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    Tuesday, June 21, 2011 5:16 PM
  • thank you sir for the clarification. :D
    Randel Ramirez
    Tuesday, June 21, 2011 5:18 PM
  • Sir, I have one more question:

    Is this only allowed for delegates?


    Randel Ramirez
    Tuesday, June 21, 2011 5:24 PM
  • Hi Randel

    The answer to your question is in your code.

    //see Main() con.MessageArrived += new MessageHandler(dis.DisplayMessage)

    I know it's a comment, but the line immediately above is an example of a client of the Connection class. In that line you are telling your program it must listen the MessageArrived event, and also where is the code block it must execute when the event occurs.

    The DisplayMessage code block must respect the MessageHandler signature, because the MessageArrived event is declared like that.

    Because the client and the Connection class use the same connector (MessageHandler delegate), the delegate is outside the Connection class.

    Whenever you need to share types between classes, you should write it alone. An example could be interfaces, you can use them in too many places in your code.

    I hope this help.

    Best regards.


    Gustavo García MCPD
    Tuesday, June 21, 2011 5:32 PM
  • Sir, I have one more question:

    Is this only allowed for delegates?


    Randel Ramirez

    Is what only allowed for delegates?

     

    Different types/members can be defined in different places.  A class or struct, for example, can be in a namespace, or inside of another class (nested classes).  A field, however, must always be in a class or struct, as it's a member of that class, and defining it outside would have no meaning.

     

    Is there a specific type you have in mind?

     


    Reed Copsey, Jr. - http://reedcopsey.com
    If a post answers your question, please click "Mark As Answer" on that post and "Mark as Helpful".
    Tuesday, June 21, 2011 5:51 PM
  • thank you again sir for clearing things up.
    Randel Ramirez
    Tuesday, June 21, 2011 5:58 PM
  • enumeration can also be defined in namespace
     
    /LM
     

    Sir, I have one more question:

    Is this only allowed for delegates?


    Randel Ramirez

    /LM
    Wednesday, June 22, 2011 3:02 AM
  • I am just learning C# and this answer is awesome, very detailed and direct. Thanks for adding another piece to my C# puzzle. Good Stuff!!!
    Monday, March 24, 2014 4:14 AM
  • Sir, I have one more question:

    Is this only allowed for delegates?


    Randel Ramirez
    Delegates are types - types are not required to be defined within other types, although they can be.  Delegates can be defined anywhere that classes/structs/enumerations/interfaces can be defined, because they are all types.

    Convert between VB, C#, C++, & Java (http://www.tangiblesoftwaresolutions.com)
    Instant C# - VB to C# Converter
    Instant VB - C# to VB Converter

    Monday, March 24, 2014 5:17 AM