Hi Guys
NP114 Moving delagate type
Following program is executing well. For curiosity I have moved public delegate void MeltdownHandler(object reactor, MeltdownEventArgs myMEA); to a different place from it’s original position (Original position is highlighted in yellow. New position is highlighted in blue).
But after moving program is not executing. Please explain the reason. How can it be altered to execuate after moving delagate type to the new position.
Thank you
using System;
public delegate void MeltdownHandler(object reactor, MeltdownEventArgs myMEA);
// declare the MeltdownEventArgs class (implements EventArgs)
class MeltdownEventArgs : EventArgs
{
// declare a private field named message
private string message;
// define a constructor
public MeltdownEventArgs(string message)
{
this.message = message;
}
// define a property to get the message
public string Message
{
get
{
return message;
}
}
}
// declare the Reactor class
class Reactor
{
// declare a private field named temperature
private int temperature;
// declare a delegate class named MeltdownHandler
//public delegate void MeltdownHandler(object reactor, MeltdownEventArgs myMEA);
// declare an event named OnMeltdown
public event MeltdownHandler OnMeltdown;
// define a property to set the temperature
public int Temperature
{
set
{
temperature = value;
// if the temperature is too high, the reactor melts down
if (temperature > 1000)
{
MeltdownEventArgs myMEA =
new MeltdownEventArgs("Reactor meltdown in progress!");
OnMeltdown(this, myMEA);
}
}
}
}
// declare the ReactorMonitor class
class ReactorMonitor
{
// define a constructor
public ReactorMonitor(Reactor myReactor)
{
myReactor.OnMeltdown += new Reactor.MeltdownHandler(DisplayMessage);
}
// define the DisplayMessage() method
public void DisplayMessage(object myReactor, MeltdownEventArgs myMEA)
{
Console.WriteLine(myMEA.Message);
}
}
public class Example12_4
{
public static void Main()
{
// create a Reactor object
Reactor myReactor = new Reactor();
// create a ReactorMonitor object
ReactorMonitor myReactorMonitor = new ReactorMonitor(myReactor);
// set myReactor.Temperature to 100 degrees Centigrade
Console.WriteLine("Setting reactor temperature to 100 degrees Centigrade");
myReactor.Temperature = 100;
// set myReactor.Temperature to 500 degrees Centigrade
Console.WriteLine("Setting reactor temperature to 500 degrees Centigrade");
myReactor.Temperature = 500;
// set myReactor.Temperature to 2000 degrees Centigrade
// (this causes the reactor to meltdown)
Console.WriteLine("Setting reactor temperature to 2000 degrees Centigrade");
myReactor.Temperature = 2000;
}
}
/*
Setting reactor temperature to 100 degrees Centigrade
Setting reactor temperature to 500 degrees Centigrade
Setting reactor temperature to 2000 degrees Centigrade
Reactor meltdown in progress!
*/
Satish KathiPosted Aug 6, 2008, 4:54 PM
MeltDownEventArgs is member of delegate. All the classes which can access the delegate must be able to access the MeltDownEventArgs.
When you declared delegate as public in class Reactor :
The access level of Reactor and MeltDownEventArgs is same. That means other classes which can access Reactor class can also access MeltDownEventArgs. Even though the delegate is declared as public in Reactor other classes can access the public delegeate only when they can access Reactor class.
But when you moved delegate out of class with public access level any class can access delegate but they cannot access MeltdownEventArgs.
Posted Aug 6, 2008, 8:20 PM
Thank you for your explanation.
Posted Aug 6, 2008, 4:23 PM
When public delegate void MeltdownHandler(object reactor, MeltdownEventArgs myMEA); is in the Reactor class no need for public accessibility, but when it is moved out public accessibility is required. Please explain the reason for that.
Posted Aug 6, 2008, 3:40 PM
Now program is executing. Thank you for your effort Satish Kumar Kathi
Satish KathiPosted Aug 6, 2008, 3:13 PM
Change the access level of the MeltdownEventArgs class to public
as
public
class MeltdownEventArgs : EventArgsPosted Aug 6, 2008, 3:01 PM
I am using Microsoft Visual C# 2008 Express Edition. When I tried to execute your code following error message is coming I don’t know why.
Inconsistent accessibility: parameter type 'MeltdownEventArgs' is less accessible than delegate 'MeltdownHandler'
Satish KathiPosted Aug 6, 2008, 2:43 PM
Following code is working perfectly
public
delegate void MeltdownHandler(object reactor, MeltdownEventArgs myMEA);// declare the MeltdownEventArgs class (implements EventArgs)
class
MeltdownEventArgs : EventArgs{
// declare a private field named message private string message;
// define a constructor public MeltdownEventArgs(string message){
this.message = message;}
// define a property to get the message public string Message{
get{
return message;}
}
}
// declare the Reactor class
class
Reactor{
// declare a private field named temperature private int temperature;
// declare a delegate class named MeltdownHandler //public delegate void MeltdownHandler(object reactor, MeltdownEventArgs myMEA);
// declare an event named OnMeltdown public event MeltdownHandler OnMeltdown;
// define a property to set the temperature public int Temperature{
set{
temperature =
value;
// if the temperature is too high, the reactor melts down if (temperature > 1000){
MeltdownEventArgs myMEA = new MeltdownEventArgs("Reactor meltdown in progress!");OnMeltdown(
this, myMEA);}
}
}
}
// declare the ReactorMonitor class
class
ReactorMonitor{
// define a constructor public ReactorMonitor(Reactor myReactor){
myReactor.OnMeltdown += new MeltdownHandler(DisplayMessage);}
// define the DisplayMessage() method public void DisplayMessage(object myReactor, MeltdownEventArgs myMEA){
Console.WriteLine(myMEA.Message);}
}
public
class Example12_4{
public static void Main(){
// create a Reactor object Reactor myReactor = new Reactor();
// create a ReactorMonitor object ReactorMonitor myReactorMonitor = new ReactorMonitor(myReactor);
// set myReactor.Temperature to 100 degrees Centigrade Console.WriteLine("Setting reactor temperature to 100 degrees Centigrade");myReactor.Temperature = 100;
// set myReactor.Temperature to 500 degrees Centigrade Console.WriteLine("Setting reactor temperature to 500 degrees Centigrade");myReactor.Temperature = 500;
// set myReactor.Temperature to 2000 degrees Centigrade // (this causes the reactor to meltdown) Console.WriteLine("Setting reactor temperature to 2000 degrees Centigrade");myReactor.Temperature = 2000;
}
}
Posted Aug 6, 2008, 2:28 PM
Satish KathiPosted Aug 6, 2008, 2:02 PM
In the first example you have declared the delegate with in the class and calling with classname.delegatename
When you moved out the delegate out of the class you have not removed the class name when you are calling the delegate
Replace following line with
myReactor.OnMeltdown += new Reactor.MeltdownHandler(DisplayMessage);// looking for delegate MeltdownHandler in Reactor class, which is not existing
with
myReactor.OnMeltdown += new MeltdownHandler(DisplayMessage);
this will work
same as the second example
bookShop.AddBook += new
AddBookEventHandler(notify.instance_AddBook);
Hope this helps
Posted Aug 6, 2008, 1:40 PM
In the following program delagate type is declared outside the class but program is executing well. What is the reason.
using System;
using System.Collections;
public delegate void AddBookEventHandler(object source, BookEventArgs e);
public class Book
{
private string title;
private string isbn;
private decimal price;
public Book(string title, string isbn, decimal price)
{
this.title = title;
this.isbn = isbn;
this.price = price;
}
public string Title
{
get { return this.title; }
}
public string ISBN
{
get { return this.isbn; }
}
public decimal Price
{
get { return this.price; }
}
}
public class BookShop
{
private ArrayList books;
private string name;
public event AddBookEventHandler AddBook;
public BookShop(string name)
{
books = new ArrayList();
this.name = name;
}
protected void OnAddBook(BookEventArgs e)
{
if (AddBook != null)
AddBook(this, e);
}
public void AddNewBook(Book book)
{
this.books.Add(book);
BookEventArgs e = new BookEventArgs(book);
OnAddBook(e);
}
}
public class BookEventArgs : EventArgs
{
private Book book;
public BookEventArgs(Book book)
{
this.book = book;
}
public Book Book
{
get { return this.book; }
}
}
public class Notifier
{
public void instance_AddBook(object source, BookEventArgs e)
{
Console.WriteLine("A Message has been sent to the Members\n" + " regarding the book '{0}' with the ISBN '{1}'\n", e.Book.Title, e.Book.ISBN);
}
}
//The Sys Class is the application that uses all the above classes.
//Let's look at the code:
public class Sys
{
public static void Main()
{
BookShop bookShop = new BookShop(".NET Bookshop");
Book b1 = new Book("The Right Way", "123456789", 19.90m);
Book b2 = new Book("The .NET Stuff", "987654321", 29.90m);
Notifier notify = new Notifier();
bookShop.AddBook += new
AddBookEventHandler(notify.instance_AddBook);
bookShop.AddNewBook(b1);
bookShop.AddNewBook(b2);
Console.ReadLine();
}
}
/*
A Message has been sent to the Members
regarding the book 'The Right Way' with the ISBN '123456789'
A Message has been sent to the Members
regarding the book 'The .NET Stuff' with the ISBN '987654321'
*/
Ryan AlfordPosted Aug 6, 2008, 12:11 PM
using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Collections;
string testString = string.Empty; // this is basically what you are doing
namespace TestClass
{
public class TestClass
{
}
}
you are declaring an object outside of a class(and namespace). After 114 questions about code snippets, you should have been able to figure this out.