Delegate for event in class

T

tshad

I was looking at a tutorial for events and can't figure out his worked with
the delegate inside the object.

using System;

namespace CustomEvents
{
public class Car
{
public delegate void OwnerChangedEventHandler(string newOwner);
public event OwnerChangedEventHandler OwnerChanged;

private string make;
private string model;
private int year;
private string owner;

public string CarMake
{
get { return this.make; }
set { this.make = value; }
}

public string CarModel
{
get { return this.model; }
set { this.model = value; }
}

public int CarYear
{
get { return this.year; }
set { this.year = value; }
}

public string CarOwner
{
get { return this.owner; }
set
{
this.owner = value;
if (this.OwnerChanged != null)
this.OwnerChanged(value);
}
}

public Car()
{
}
}
}

If I do this in my main routine:

Car car = new Car();

//adds an event handler to the OwnerChanged event
car.OwnerChanged += new OwnerChangedEventHandler(car_OwnerChanged);

//setting this will fire the OwnerChanged event
car.CarOwner = "The Reddest";

I get an error on the "new OwnerChangedEventHandler" saying that
OwnerChangedEventHandler doesn't exist.

If I moved the delegate to before the car class:

**************************************

class Program
{
public delegate void OwnerChangedEventHandler(string newOwner);

public class Car
{
**************************************

Now it works fine.

Am I missing something in the article?

I get that the delegate is in the class not the object - but why did it work
in the article.

It was the last example in the article:

http://www.switchonthecode.com/tutorials/csharp-snippet-tutorial-custom-event-handlers

Thanks,

Tom
 
P

Peter Duniho

tshad said:
[...]
I get an error on the "new OwnerChangedEventHandler" saying that
OwnerChangedEventHandler doesn't exist.

If I moved the delegate to before the car class:

**************************************

class Program
{
public delegate void OwnerChangedEventHandler(string newOwner);

public class Car
{
**************************************

Now it works fine.

Am I missing something in the article?

I get that the delegate is in the class not the object - but why did it work
in the article.

I don't understand what you mean by "why did it work in the article".
The article doesn't, as near as I can tell, provide a complete code
example. The code in the article _doesn't_ work, at all. Not unless
you add something to it.

One of the commenters to the article has already pointed out how to get
the delegate type from outside the containing class (i.e. qualify the
type name with the name of the containing class, as in
"Car.OwnerChangedEventHandler"), and perhaps you already understand that
part.

But asking why the code works in the article doesn't make any sense to
me. It _couldn't_ work as posted unless the code was referencing the
type from within the Car class itself (*), and the code in the article
doesn't work in any case (since it's not complete).

Pete

(*) Actually, that statement isn't really true. It's true enough, given
what code was available in the example. But as long as we're assuming
arbitrary code added to the example to make it work, we could actually
assume the code includes a "using" directive to define a type alias.
So, you could have code that looks like this:


using System;
using CustomEvents;
using OwnerChangedEventHandler = CustomEvents.Car.OwnerChangedEventHandler;

namespace Test
{
static void Main(string[] args)
{
Car car = new Car();

car.OwnerChanged += new OwnerChangedEventHandler(car_OwnerChanged);
}

static void car_OwnerChanged(string newOwner)
{
}
}


And for that matter, you could side-step the entire issue by letting the
compiler infer the type and instantiate the delegate for you:


using System;
using CustomEvents;

namespace Test
{
static void Main(string[] args)
{
Car car = new Car();

car.OwnerChanged += car_OwnerChanged;
}

static void car_OwnerChanged(string newOwner)
{
}
}


If you never actually have to write the type name, then of course it
doesn't matter whether you know how to write it correctly. :)
 
T

tshad

Peter Duniho said:
tshad said:
[...]
I get an error on the "new OwnerChangedEventHandler" saying that
OwnerChangedEventHandler doesn't exist.

If I moved the delegate to before the car class:

**************************************

class Program
{
public delegate void OwnerChangedEventHandler(string newOwner);

public class Car
{
**************************************

Now it works fine.

Am I missing something in the article?

I get that the delegate is in the class not the object - but why did it
work in the article.

I don't understand what you mean by "why did it work in the article". The
article doesn't, as near as I can tell, provide a complete code example.
The code in the article _doesn't_ work, at all. Not unless you add
something to it.

What I meant was that the responses seemed to say the code worked (which is
does when you add something to it as you said).

but the last two panels have the delegate inside the class and the
instantiating of the delegate without the object name.

Would have been better if he had either put the delegate before the class or
put the object name on it (car.OwnerChangedEventHandler) just to be clear.
One of the commenters to the article has already pointed out how to get
the delegate type from outside the containing class (i.e. qualify the type
name with the name of the containing class, as in
"Car.OwnerChangedEventHandler"), and perhaps you already understand that
part.
I did.

Just couldn't figure out how to make his code work as written.
But asking why the code works in the article doesn't make any sense to me.
It _couldn't_ work as posted unless the code was referencing the type from
within the Car class itself (*), and the code in the article doesn't work
in any case (since it's not complete).

Pete

(*) Actually, that statement isn't really true. It's true enough, given
what code was available in the example. But as long as we're assuming
arbitrary code added to the example to make it work, we could actually
assume the code includes a "using" directive to define a type alias.

Why would you assume that?

It was supposed to be a simple example that was easy to understand.
So, you could have code that looks like this:


using System;
using CustomEvents;
using OwnerChangedEventHandler =
CustomEvents.Car.OwnerChangedEventHandler;

namespace Test
{
static void Main(string[] args)
{
Car car = new Car();

car.OwnerChanged += new OwnerChangedEventHandler(car_OwnerChanged);
}

static void car_OwnerChanged(string newOwner)
{
}
}

I probably wouldn't do it that way. But it does work.
And for that matter, you could side-step the entire issue by letting the
compiler infer the type and instantiate the delegate for you:


using System;
using CustomEvents;

namespace Test
{
static void Main(string[] args)
{
Car car = new Car();

car.OwnerChanged += car_OwnerChanged;
}

static void car_OwnerChanged(string newOwner)
{
}
}


If you never actually have to write the type name, then of course it
doesn't matter whether you know how to write it correctly. :)

True.

Didn't know you could do it that way.

I was surprised that you could do it that way and put the delegate before or
after the class statement.

I would have thought it would have failed with the delegate inside the class
statement just like the original one did:

car.OwnerChanged += new OwnerChangedEventHandler(car_OwnerChanged);

Thanks,

Tom
 
P

Peter Duniho

tshad said:
[...]
Would have been better if he had either put the delegate before the class or
put the object name on it (car.OwnerChangedEventHandler) just to be clear.

Sure. But that's feedback for the author of the article. We can't do
much about it here. :)
[...]
(*) Actually, that statement isn't really true. It's true enough, given
what code was available in the example. But as long as we're assuming
arbitrary code added to the example to make it work, we could actually
assume the code includes a "using" directive to define a type alias.

Why would you assume that?

So that you could get the code the work.
[...]
Didn't know you could do it that way.

I was surprised that you could do it that way and put the delegate before or
after the class statement.

I would have thought it would have failed with the delegate inside the class
statement just like the original one did:

car.OwnerChanged += new OwnerChangedEventHandler(car_OwnerChanged);

Why would you think that? The type is visible to the compiler, and
without you typing the name of the type at all, there's no way for it to
be typed wrong. As you already understand, you can simply type the name
correctly, as "Car.OwnerChnagedEventHandler" and it works. So, if you
just let the compiler infer that type name instead, why wouldn't it work?

It's not just a rhetorical question. I'm trying to understand what,
given the example, can be difficult to understand for people trying to
learn how to do this. If you can explain why you would come to the
conclusion you did, that could help me in the future avoid confusion
about such conclusions.

Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top