By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
439,978 Members | 1,373 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 439,978 IT Pros & Developers. It's quick & easy.

Why does this object need to be cast?

P: n/a
In this sample code of ownerdraw drawmode, why does the '(ComboBox) sender'
line of code need to be there in this event handler?
Isn't cboFont passed via the managed heap, not the stack, into this
cboFont_DrawItem event handler? Why does it need to be cast? -hazz

,.................
cboFont.Items.AddRange(FontFamily.Families);
}

private void cboFont_DrawItem(object sender,
System.Windows.Forms.DrawItemEventArgs e) {

ComboBox cboFont = (ComboBox) sender; .........,
Nov 16 '05 #1
Share this Question
Share on Google+
17 Replies


P: n/a
Hi,

The signature of the event is EventHandler( object sender, EventArgs e )

meaning that you have to cast sender to the correct type.

You will find this situation almost everywhere.

Cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation
"Hazz" <ha**@nospameroosonic.net> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
In this sample code of ownerdraw drawmode, why does the '(ComboBox)
sender' line of code need to be there in this event handler?
Isn't cboFont passed via the managed heap, not the stack, into this
cboFont_DrawItem event handler? Why does it need to be cast? -hazz

,.................
cboFont.Items.AddRange(FontFamily.Families);
}

private void cboFont_DrawItem(object sender,
System.Windows.Forms.DrawItemEventArgs e) {

ComboBox cboFont = (ComboBox) sender; .........,

Nov 16 '05 #2

P: n/a
Thank you Ignacio but I guess I didn't ask my question clearly.
If the eventhandler will never handle anything other than (in this case)
comboboxes, why do I need to cast to comboboxes?
Is it because sender is of a generic object type? Does the runtime not know
that this is an object of type combobox?
If I am passing by reference rather than by value, doesn't the heap retain
the combobox info? Or is this a metadata thing?
Is that why I also often see the 'TypeOf' keyword at the beginning of a
method, to test to see if perhaps this object that is passed in as an
argument is of the type Combobox? Or is this for some other reason?
thx, -hazz
"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us> wrote
in message news:e1*************@TK2MSFTNGP12.phx.gbl...
Hi,

The signature of the event is EventHandler( object sender, EventArgs e )

meaning that you have to cast sender to the correct type.

You will find this situation almost everywhere.

Cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation
"Hazz" <ha**@nospameroosonic.net> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
In this sample code of ownerdraw drawmode, why does the '(ComboBox)
sender' line of code need to be there in this event handler?
Isn't cboFont passed via the managed heap, not the stack, into this
cboFont_DrawItem event handler? Why does it need to be cast? -hazz

,.................
cboFont.Items.AddRange(FontFamily.Families);
}

private void cboFont_DrawItem(object sender,
System.Windows.Forms.DrawItemEventArgs e) {

ComboBox cboFont = (ComboBox) sender; .........,


Nov 16 '05 #3

P: n/a

"Hazz" <ha**@nospameroosonic.net> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
Thank you Ignacio but I guess I didn't ask my question clearly.
If the eventhandler will never handle anything other than (in this case)
comboboxes, why do I need to cast to comboboxes?
Is it because sender is of a generic object type? Does the runtime not
know that this is an object of type combobox?
If I am passing by reference rather than by value, doesn't the heap retain
the combobox info? Or is this a metadata thing?
Is that why I also often see the 'TypeOf' keyword at the beginning of a
method, to test to see if perhaps this object that is passed in as an
argument is of the type Combobox? Or is this for some other reason?
thx, -hazz


First thing, don't use the word generic to describe something general. This
will just make you confused when you move to .NET 2.0 and actually have
generic types.

As for your problem. The event handler is defined by a general delegate that
is used all over the .NET framework for simple events. Hence even though
your combobox knows its type, the delegate does not and you must resort to
downcasting.

The combobox triggers the event and sends itself as sender and in the
process it gets upcasted to Object. In order to access the the instance as
more than a Object you must downcast it to an appropriate type. If you only
need it's name you could downcast to Component and if you need it's position
you could downcast to Control. However, if you want to know it's selcected
item you need to downcast to ComboBox.

Downcasting is dangerous as you must know what type the instance can be cast
to. This is what generics will try to solve for us with parameterized types.
It's a very nifty thing to have.

..NET is not only about managed data (ie having a garbage collector) but also
managed code. Hence if you try to downcast an instance of a ComboBox from an
Object-reference into a StringBuilder the Common Language Runtime (CLR) will
check if it's an ok cast and throw a InvalidCastException if you tried.

The same is not true for unmanaged code like C++ and Delphi. If you make an
illegal cast you really screw things up and you wind up with a reference
pointing to one type of object using methods of the wrong class, typically
giving you the infamous 'General Protection Fault' or 'Access Violation'
exception when the code being called makes non sense. This is also why C++
and Delphi sport much better performance than .NET and Java. The former
don't check what we do and the latter hold our hands while we do it.

Casts in C# is actually methods, called cast operators, even though they get
very much optimized by the CIL-compiler for most types in the Common Type
System (CTS).

C# introduces two types of cast operators; implict- and explicit-casts.
Example with cast operators on System.Byte and System.Int32:

myInt = myByte; //implicit cast, a 8-bit can always become an 32-bit
myByte = (Byte)myInt; //explicit cast needed as an int may contain a large
value which throws an exception.

If you define a class in C# you can supply it with your own cast operators.
Hence a subclass called MyComboBox could very much become a StringBuilder,
if you'd want. =)

But note the smiley. You should be very careful before overloading
operators, even cast operators. Cast operators should only be used when
there is a natural and simple conversion from one type to another. Note how
a System.Byte can be cast to System.Int32 without effort and therefor
supports a cast operator for it, while making it into a string involve
actual work and so you must call the method.ToString()

Hope this made you less confused.=)

- Michael S


Nov 16 '05 #4

P: n/a
Thank you Michael!
Having just attended an all day 'generics' education day, your point is well
taken about sloppy use of the term 'generic.'
Moreover, your explanation helped me to better understand why I would want
to use generics rather than 'just' how.
I think I followed you very well with your explanation. If you are so
inclined, would you say anything about the 'typeof' keyword as it is often
used and how that might change with the use of .NET 2.0's generics? Or is
this apples and oranges?
In any case, thank you so much for the explanation you already
rovided. -hazz

"Michael S" <a@b.c> wrote in message
news:uJ*************@TK2MSFTNGP15.phx.gbl...

"Hazz" <ha**@nospameroosonic.net> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
Thank you Ignacio but I guess I didn't ask my question clearly.
If the eventhandler will never handle anything other than (in this case)
comboboxes, why do I need to cast to comboboxes?
Is it because sender is of a generic object type? Does the runtime not
know that this is an object of type combobox?
If I am passing by reference rather than by value, doesn't the heap
retain the combobox info? Or is this a metadata thing?
Is that why I also often see the 'TypeOf' keyword at the beginning of a
method, to test to see if perhaps this object that is passed in as an
argument is of the type Combobox? Or is this for some other reason?
thx, -hazz


First thing, don't use the word generic to describe something general.
This will just make you confused when you move to .NET 2.0 and actually
have generic types.

As for your problem. The event handler is defined by a general delegate
that is used all over the .NET framework for simple events. Hence even
though your combobox knows its type, the delegate does not and you must
resort to downcasting.

The combobox triggers the event and sends itself as sender and in the
process it gets upcasted to Object. In order to access the the instance as
more than a Object you must downcast it to an appropriate type. If you
only need it's name you could downcast to Component and if you need it's
position you could downcast to Control. However, if you want to know it's
selcected item you need to downcast to ComboBox.

Downcasting is dangerous as you must know what type the instance can be
cast to. This is what generics will try to solve for us with parameterized
types. It's a very nifty thing to have.

.NET is not only about managed data (ie having a garbage collector) but
also managed code. Hence if you try to downcast an instance of a ComboBox
from an Object-reference into a StringBuilder the Common Language Runtime
(CLR) will check if it's an ok cast and throw a InvalidCastException if
you tried.

The same is not true for unmanaged code like C++ and Delphi. If you make
an illegal cast you really screw things up and you wind up with a
reference pointing to one type of object using methods of the wrong class,
typically giving you the infamous 'General Protection Fault' or 'Access
Violation' exception when the code being called makes non sense. This is
also why C++ and Delphi sport much better performance than .NET and Java.
The former don't check what we do and the latter hold our hands while we
do it.

Casts in C# is actually methods, called cast operators, even though they
get very much optimized by the CIL-compiler for most types in the Common
Type System (CTS).

C# introduces two types of cast operators; implict- and explicit-casts.
Example with cast operators on System.Byte and System.Int32:

myInt = myByte; //implicit cast, a 8-bit can always become an 32-bit
myByte = (Byte)myInt; //explicit cast needed as an int may contain a large
value which throws an exception.

If you define a class in C# you can supply it with your own cast
operators. Hence a subclass called MyComboBox could very much become a
StringBuilder, if you'd want. =)

But note the smiley. You should be very careful before overloading
operators, even cast operators. Cast operators should only be used when
there is a natural and simple conversion from one type to another. Note
how a System.Byte can be cast to System.Int32 without effort and therefor
supports a cast operator for it, while making it into a string involve
actual work and so you must call the method.ToString()

Hope this made you less confused.=)

- Michael S


Nov 16 '05 #5

P: n/a

"Hazz" <ha**@nospameroosonic.net> wrote in message
news:uI**************@tk2msftngp13.phx.gbl...
Thank you Michael!
Having just attended an all day 'generics' education day, your point is
well taken about sloppy use of the term 'generic.'
Moreover, your explanation helped me to better understand why I would want
to use generics rather than 'just' how.
- Thanks. I've held a couple of informal lectures on generics, and it's when
I mention the problem with downcasts people get it. Generics will save us
alot of stupid downcast-bugs in .NET 2.0
I think I followed you very well with your explanation. If you are so
inclined, would you say anything about the 'typeof' keyword as it is often
used and how that might change with the use of .NET 2.0's generics? Or is
this apples and oranges?
In any case, thank you so much for the explanation you already
ovided. -hazz


I seldom see the 'typeof' keyword in code but often the 'is' keyword. Always
something like this:

if (myObject is StringBuilder)
{
((StringBuilder)myObject).Append("I think I am doing the right thing!");
}
else
{
throw new Exception("Oops, I did the wrong thing. I hate this f**king
job!");
}

The above code may look sound for a Delphi or C++ developer where a direct
cast can have severe side-effects, but the .NET framework protect us. Many
people still don't get the value of managed code. Hence the above code is
just bloat and I would rather see just this:

((StringBuilder)myObject).Append("This just should work or I have no brains.
..NET will stop me if I'm stupid!");

In .NET both pieces of code do the exact same thing, appends a string to a
StringBuilder or throw an exception if it is in error. But the latter is
more neat as it:

1) is short and to the point.
2) says to the maintainer that it really wants a StringBuilder and have no
'what-if' or 'why-not' conditions.
3) will not throw the most general Exception there is, with a silly
errormessage that might reach the user.
4) will have the CLR throw a very defined InvalidCastException for us, and
by so showing us that we have a bug.

My point being, do not code checks in .NET that the CLR will check for you.
If .NET throws an excpetion, it's a bug. Log it, mail it, do whatever stuff
you want with it, but don't protect yourself from it.

My true point being: if you're gonna downcast; - Be bold and make sure you
do it right!

- Michael S
Nov 16 '05 #6

P: n/a
simple elegance through understanding..... got it Michael... thank you
very much.

"Michael S" <a@b.c> wrote in message
news:eG**************@TK2MSFTNGP14.phx.gbl...

"Hazz" <ha**@nospameroosonic.net> wrote in message
news:uI**************@tk2msftngp13.phx.gbl...
Thank you Michael!
Having just attended an all day 'generics' education day, your point is
well taken about sloppy use of the term 'generic.'
Moreover, your explanation helped me to better understand why I would
want to use generics rather than 'just' how.


- Thanks. I've held a couple of informal lectures on generics, and it's
when I mention the problem with downcasts people get it. Generics will
save us alot of stupid downcast-bugs in .NET 2.0
I think I followed you very well with your explanation. If you are so
inclined, would you say anything about the 'typeof' keyword as it is
often used and how that might change with the use of .NET 2.0's generics?
Or is this apples and oranges?
In any case, thank you so much for the explanation you already
vided. -hazz


I seldom see the 'typeof' keyword in code but often the 'is' keyword.
Always something like this:

if (myObject is StringBuilder)
{
((StringBuilder)myObject).Append("I think I am doing the right thing!");
}
else
{
throw new Exception("Oops, I did the wrong thing. I hate this f**king
job!");
}

The above code may look sound for a Delphi or C++ developer where a direct
cast can have severe side-effects, but the .NET framework protect us. Many
people still don't get the value of managed code. Hence the above code is
just bloat and I would rather see just this:

((StringBuilder)myObject).Append("This just should work or I have no
brains. .NET will stop me if I'm stupid!");

In .NET both pieces of code do the exact same thing, appends a string to a
StringBuilder or throw an exception if it is in error. But the latter is
more neat as it:

1) is short and to the point.
2) says to the maintainer that it really wants a StringBuilder and have no
'what-if' or 'why-not' conditions.
3) will not throw the most general Exception there is, with a silly
errormessage that might reach the user.
4) will have the CLR throw a very defined InvalidCastException for us, and
by so showing us that we have a bug.

My point being, do not code checks in .NET that the CLR will check for
you. If .NET throws an excpetion, it's a bug. Log it, mail it, do whatever
stuff you want with it, but don't protect yourself from it.

My true point being: if you're gonna downcast; - Be bold and make sure you
do it right!

- Michael S

Nov 16 '05 #7

P: n/a
Michael S <a@b.c> wrote:

<snip>
My point being, do not code checks in .NET that the CLR will check for you.
If .NET throws an excpetion, it's a bug. Log it, mail it, do whatever stuff
you want with it, but don't protect yourself from it.


That's only true if the caller is definitely meant to pass in an
instance of the specific type though.

Consider a method which copies the contents of one stream to another -
if a MemoryStream is passed in, the MemoryStream.WriteTo method is the
fastest way of going; otherwise, you need to copy block by block. That
could be written:

MemoryStream ms = sourceStream as MemoryStream;
if (ms != null)
{
ms.CopyTo (destStream);
}
else
{
...
}

Nothing wrong with that.

Where you're going to throw an exception if the object is the wrong
type, there may still be value in throwing a different exception to the
default InvalidCastException - for instance, throwing an
InvalidArgumentException may be more appropriate (and allows you to
specify which parameter was wrong).

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #8

P: n/a
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Michael S <a@b.c> wrote:

<snip>
My point being, do not code checks in .NET that the CLR will check for
you.
If .NET throws an excpetion, it's a bug. Log it, mail it, do whatever
stuff
you want with it, but don't protect yourself from it.
That's only true if the caller is definitely meant to pass in an
instance of the specific type though.


-It typically is just so for applications. When we build applications we
only sew things up for which with managed code we have protection. For
writing low level classes, overiding operators and such, Exception handling
should be mandatory. But for applications, we should rely on the protection
and the documentation there is.

This is the Java pitfall with checked exceptions. It goes like this:

When I write a method in Java, I might receive a reference type. Hence I
better by a good java-dev and check for null first and type then. This
implies I have to throw two checked exceptions. But the one calling the
method knows very well that the object is there and is of the right type.
But stand no chance no less. The caller must do a silly try/catch or forward
it upwards which makes even less sense.

The caller will sport code that implies that something may go wrong when it
cannot possibly do so.

I like Anders Hjelsbergs view on this. - Never force a caller to handle
exceptions. Good code have a finally/catch ratio of 10 to 1.
Consider a method which copies the contents of one stream to another -
if a MemoryStream is passed in, the MemoryStream.WriteTo method is the
fastest way of going; otherwise, you need to copy block by block. That
could be written: ---
*snip*
---
Nothing wrong with that.
- Nothing wrong if you're writing a general component. But if you're
building an application, you fool the maintainer as to beleive that the
stream may or not work, when it always does. Hence the protection is not
only overkill, but may take the maintainer on a short, but dead end, trail
while debugging.

Where you're going to throw an exception if the object is the wrong
type, there may still be value in throwing a different exception to the
default InvalidCastException - for instance, throwing an
InvalidArgumentException may be more appropriate (and allows you to
specify which parameter was wrong).
- This may be true for C++ and Delphi, as bugs in a release compile often
just yields an access violation and a hexcode address. But for managed code,
most developers just want to find the .cs file and line-number to fix the
darn simple bug.

Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too


- Thanks Mr. Skeet. Looking forward to your reply.

- Michael S
Nov 16 '05 #9

P: n/a
Michael S <a@b.c> wrote:
That's only true if the caller is definitely meant to pass in an
instance of the specific type though.
-It typically is just so for applications. When we build applications we
only sew things up for which with managed code we have protection. For
writing low level classes, overiding operators and such, Exception handling
should be mandatory. But for applications, we should rely on the protection
and the documentation there is.


Well, I'm in favour of sparingly used checked exceptions, but there we
go.
This is the Java pitfall with checked exceptions. It goes like this:

When I write a method in Java, I might receive a reference type. Hence I
better by a good java-dev and check for null first and type then. This
implies I have to throw two checked exceptions. But the one calling the
method knows very well that the object is there and is of the right type.
But stand no chance no less. The caller must do a silly try/catch or forward
it upwards which makes even less sense.
Why should it have to throw two checked exceptions? There's are two
perfectly good unchecked exception types specifically for those cases.
The caller will sport code that implies that something may go wrong when it
cannot possibly do so.

I like Anders Hjelsbergs view on this. - Never force a caller to handle
exceptions.
I prefer "force a caller to handle exceptions they might reasonably
recover from, but not others". In my current Java work I'll be using
unchecked exceptions quite a lot - and checked exceptions on occasion,
where I really want to make sure I think about handling them.
Good code have a finally/catch ratio of 10 to 1.


Agreed.
Consider a method which copies the contents of one stream to another -
if a MemoryStream is passed in, the MemoryStream.WriteTo method is the
fastest way of going; otherwise, you need to copy block by block. That
could be written:

---
*snip*
---
Nothing wrong with that.


- Nothing wrong if you're writing a general component. But if you're
building an application, you fool the maintainer as to beleive that the
stream may or not work, when it always does. Hence the protection is not
only overkill, but may take the maintainer on a short, but dead end, trail
while debugging.


Why should the maintainer believe that the stream may or may not work,
when both branches of the "if" statement have valid paths? It's not
exactly hard-to-read code, and there's nothing which explicitly throws
an exception there.
Where you're going to throw an exception if the object is the wrong
type, there may still be value in throwing a different exception to the
default InvalidCastException - for instance, throwing an
InvalidArgumentException may be more appropriate (and allows you to
specify which parameter was wrong).


- This may be true for C++ and Delphi, as bugs in a release compile often
just yields an access violation and a hexcode address. But for managed code,
most developers just want to find the .cs file and line-number to fix the
darn simple bug.


So you don't see any value in the message or type at all? Bear in mind
that the bug may not be found until after release - at which point
there may not be line numbers available at all... Sure, in an ideal
world all bugs would be found before deployment, but in my experience
that just doesn't happen.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #10

P: n/a

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
Michael S <a@b.c> wrote: Why should the maintainer believe that the stream may or may not work,
when both branches of the "if" statement have valid paths? It's not
exactly hard-to-read code, and there's nothing which explicitly throws
an exception there.
It is hard to read if you have to make something work in 15 minutes. =)

So you don't see any value in the message or type at all? Bear in mind
that the bug may not be found until after release - at which point
there may not be line numbers available at all... Sure, in an ideal
world all bugs would be found before deployment, but in my experience
that just doesn't happen.


Maybe this is why we need to fix things in 15 minutes. =)

Anyways, I'll repost the Anders Hjelsberg on checked exceptions.

Part II, the problems with checked exceptions:
http://www.artima.com/intv/handcuffs.html

The index: http://www.artima.com/intv/anders.html

Thanks Jon.

- Michael S
Nov 16 '05 #11

P: n/a
Hazz, in addition to Michaels good points, there's another one to consider:
textBox1.Click += new EventHandler(MyClickHandler);
comboBox1.Click += new EventHandler(MyClickHandler);

The fact that the delegate uses object rather than a strongly typed sender
parameter allows you to be far more flexible in handling standard events. If
they were strongly typed and you wanted to trap the Click event of every
control, you'd have to create an event handler for each type of control you
have on your form. Where it gets really fun is when you don't know that at
design time. Using object completely bypasses all these issues, at the
fairly minor cost of having to cast your sender referenced when you need to
use them.

"Hazz" <ha**@nospameroosonic.net> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
Thank you Ignacio but I guess I didn't ask my question clearly.
If the eventhandler will never handle anything other than (in this case)
comboboxes, why do I need to cast to comboboxes?
Is it because sender is of a generic object type? Does the runtime not
know that this is an object of type combobox?
If I am passing by reference rather than by value, doesn't the heap retain
the combobox info? Or is this a metadata thing?
Is that why I also often see the 'TypeOf' keyword at the beginning of a
method, to test to see if perhaps this object that is passed in as an
argument is of the type Combobox? Or is this for some other reason?
thx, -hazz
"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us>
wrote in message news:e1*************@TK2MSFTNGP12.phx.gbl...
Hi,

The signature of the event is EventHandler( object sender, EventArgs e )

meaning that you have to cast sender to the correct type.

You will find this situation almost everywhere.

Cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation
"Hazz" <ha**@nospameroosonic.net> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
In this sample code of ownerdraw drawmode, why does the '(ComboBox)
sender' line of code need to be there in this event handler?
Isn't cboFont passed via the managed heap, not the stack, into this
cboFont_DrawItem event handler? Why does it need to be cast? -hazz

,.................
cboFont.Items.AddRange(FontFamily.Families);
}

private void cboFont_DrawItem(object sender,
System.Windows.Forms.DrawItemEventArgs e) {

ComboBox cboFont = (ComboBox) sender; .........,



Nov 16 '05 #12

P: n/a
Michael S <a@b.c> wrote:
Why should the maintainer believe that the stream may or may not work,
when both branches of the "if" statement have valid paths? It's not
exactly hard-to-read code, and there's nothing which explicitly throws
an exception there.
It is hard to read if you have to make something work in 15 minutes. =)


Here's a sample (untested) implementation:

/// <summary>
/// Copies the contents of one stream to another. The source
/// stream should be at the start before the method is called,
/// otherwise the results are undefined.
/// </summary>
/// <param name="source">Stream to copy from</param>
/// <param name="dest">Stream to copy to</param>
static void CopyStream (Stream source, Stream dest)
{
// Optimise for memory streams
MemoryStream ms = source as MemoryStream;
if (ms != null)
{
ms.WriteTo(dest);
}
else // No optimisation - just copy a block at a time
{
byte[] buffer = new byte[8*1024];
int bytesRead;
while ((bytesRead=source.Read(buffer, 0, buffer.Length))>0)
{
dest.Write(buffer, 0, bytesRead);
}
}
}

What would make the maintainer think that either branch is a failure?
You really don't have to be particularly competent to see what's going
on - even without the comments I think it would be pretty clear.
So you don't see any value in the message or type at all? Bear in mind
that the bug may not be found until after release - at which point
there may not be line numbers available at all... Sure, in an ideal
world all bugs would be found before deployment, but in my experience
that just doesn't happen.


Maybe this is why we need to fix things in 15 minutes. =)


I certainly agree that code needs to be readable - I just don't think
that my code above is hard to read, and the performance improvement can
be significant.
Anyways, I'll repost the Anders Hjelsberg on checked exceptions.

Part II, the problems with checked exceptions:
http://www.artima.com/intv/handcuffs.html

The index: http://www.artima.com/intv/anders.html


I've read it before, and never agreed entirely with it. He has some
good points, and some bad.

In particular, the claim that people are declaring "throws Exception"
in all kinds of Java code is incorrect in my experience - or at least,
things are no better in the C# world where I see plenty of code with

catch (Exception e)
{
....
}

or just

catch
{
....
}

I think checked exceptions have historically been overused, but that
doesn't mean they're a bad thing per se.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #13

P: n/a
Thanks Sean. I get that now. I am going to have to write some test code
to play around with some of these ideas. -hazz

"Sean Hederman" <us***@blogentry.com> wrote in message
news:cv**********@ctb-nnrp2.saix.net...
Hazz, in addition to Michaels good points, there's another one to
consider:
textBox1.Click += new EventHandler(MyClickHandler);
comboBox1.Click += new EventHandler(MyClickHandler);

The fact that the delegate uses object rather than a strongly typed sender
parameter allows you to be far more flexible in handling standard events.
If they were strongly typed and you wanted to trap the Click event of
every control, you'd have to create an event handler for each type of
control you have on your form. Where it gets really fun is when you don't
know that at design time. Using object completely bypasses all these
issues, at the fairly minor cost of having to cast your sender referenced
when you need to use them.

"Hazz" <ha**@nospameroosonic.net> wrote in message
news:%2****************@tk2msftngp13.phx.gbl...
Thank you Ignacio but I guess I didn't ask my question clearly.
If the eventhandler will never handle anything other than (in this case)
comboboxes, why do I need to cast to comboboxes?
Is it because sender is of a generic object type? Does the runtime not
know that this is an object of type combobox?
If I am passing by reference rather than by value, doesn't the heap
retain the combobox info? Or is this a metadata thing?
Is that why I also often see the 'TypeOf' keyword at the beginning of a
method, to test to see if perhaps this object that is passed in as an
argument is of the type Combobox? Or is this for some other reason?
thx, -hazz
"Ignacio Machin ( .NET/ C# MVP )" <ignacio.machin AT dot.state.fl.us>
wrote in message news:e1*************@TK2MSFTNGP12.phx.gbl...
Hi,

The signature of the event is EventHandler( object sender, EventArgs e )

meaning that you have to cast sender to the correct type.

You will find this situation almost everywhere.

Cheers,

--
Ignacio Machin,
ignacio.machin AT dot.state.fl.us
Florida Department Of Transportation
"Hazz" <ha**@nospameroosonic.net> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...
In this sample code of ownerdraw drawmode, why does the '(ComboBox)
sender' line of code need to be there in this event handler?
Isn't cboFont passed via the managed heap, not the stack, into this
cboFont_DrawItem event handler? Why does it need to be cast? -hazz

,.................
cboFont.Items.AddRange(FontFamily.Families);
}

private void cboFont_DrawItem(object sender,
System.Windows.Forms.DrawItemEventArgs e) {

ComboBox cboFont = (ComboBox) sender; .........,



Nov 16 '05 #14

P: n/a
> If the eventhandler will never handle anything other than (in this
case)
comboboxes, why do I need to cast to comboboxes?
Is it because sender is of a generic object type? Does the runtime not know that this is an object of type combobox?
If I am passing by reference rather than by value, doesn't the heap retain the combobox info?


Be careful here. You are confusing compile-time and run-time concepts.

The explicit cast does two things:

1. It is your "promise" to the compiler that, yes, this thing that is
declared as "object" will be, at run time, a ComboBox, or a type
compatible with ComboBox (such as a child class).

2. Because the compiler doesn't completely trust you, it generates code
to verify that the cast is valid at run-time.

A "cast" absolutely does not _change_ what type of object this is at
run time. Nothing can do that. After you've instantiated a ComboBox it
is a ComboBox forever. What the cast does is gives the compiler the
warm fuzzies: "I, as a programmer, know that the thing that I put in
this "object" reference is a ComboBox. So, just pretend it's a ComboBox
and let's get on with this."

The compiler has no way to know what the variable "sender" will refer
to at run-time, so you have to give it some help.

The "typeof" operator is useful when even you, great programmer that
you are, aren't sure what kind of thing an "object" variable (for
example) refers to. "typeof" generates code to ask, _at run time_, what
kind of thing this is. It is typically then followed by a cast to cast
a more general type (such as "object") to something more specific that
you can work with (such as ComboBox), after you've determined via
"typeof" that it is, indeed, a type compatible with ComboBox.

Take care not to confuse compile time and run time; compile time has,
in many respects, less information available to it, an you often have
to make assurances to the compiler (via things like casts) that you
know what you're doing.

Nov 16 '05 #15

P: n/a

"Sean Hederman" <us***@blogentry.com> wrote in message
news:cv**********@ctb-nnrp2.saix.net...
The fact that the delegate uses object rather than a strongly typed sender
parameter allows you to be far more flexible in handling standard events.
If they were strongly typed and you wanted to trap the Click event of
every control, you'd have to create an event handler for each type of
control you have on your form. Where it gets really fun is when you don't
know that at design time. Using object completely bypasses all these
issues, at the fairly minor cost of having to cast your sender referenced
when you need to use them.


Well said!

- Michael S
Nov 16 '05 #16

P: n/a

"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om...
What would make the maintainer think that either branch is a failure?
You really don't have to be particularly competent to see what's going
on - even without the comments I think it would be pretty clear.
Nothing. You optimize for certain subclasses. Great!

I certainly agree that code needs to be readable - I just don't think
that my code above is hard to read, and the performance improvement can
be significant.
The code above is obvious. Ther is no need for simplification nor any
comments in code.
But the code above is not an example of what I'm talking about, like doing
silly stuff like checking for null etc etc.
I've read it before, and never agreed entirely with it. He has some
good points, and some bad.
I can't see the bad points. Not even the the one below. I have read most the
stuff you've written and I'm curious about your thoughts on this...

In particular, the claim that people are declaring "throws Exception"
in all kinds of Java code is incorrect in my experience - or at least,
things are no better in the C# world where I see plenty of code with
*snip*
I think checked exceptions have historically been overused, but that
doesn't mean they're a bad thing per se.


I think the 'as' keyord is great in C#. And in your stream example you use
to show that the object may not be of a certain type and test for it. I
think exceptions are overused in both Java and .NET. My point is still -
Keep it simple and let the driver drive. Hence, a method should not check
its params for null, let the consumer of the method check if a reference
points to an object.

- Michael S
Nov 16 '05 #17

P: n/a
Michael S <a@b.c> wrote:
I certainly agree that code needs to be readable - I just don't think
that my code above is hard to read, and the performance improvement can
be significant.


The code above is obvious. Ther is no need for simplification nor any
comments in code.
But the code above is not an example of what I'm talking about, like doing
silly stuff like checking for null etc etc.


Why is checking for null silly? It makes sure you throw a useful
exception - and that you throw it before you do other things to change
the state. (If possible, a method call which fails should fail without
having done anything.)
I've read it before, and never agreed entirely with it. He has some
good points, and some bad.


I can't see the bad points. Not even the the one below. I have read most the
stuff you've written and I'm curious about your thoughts on this...

In particular, the claim that people are declaring "throws Exception"
in all kinds of Java code is incorrect in my experience - or at least,
things are no better in the C# world where I see plenty of code with


*snip*
I think checked exceptions have historically been overused, but that
doesn't mean they're a bad thing per se.


I think the 'as' keyord is great in C#. And in your stream example you use
to show that the object may not be of a certain type and test for it. I
think exceptions are overused in both Java and .NET. My point is still -
Keep it simple and let the driver drive. Hence, a method should not check
its params for null, let the consumer of the method check if a reference
points to an object.


That leaves you open for methods which "half work" - and which don't
help you diagnose what you actually did wrong when you get an
exception.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #18

This discussion thread is closed

Replies have been disabled for this discussion.