
Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Hello!
The book is called Microsoft Visual C# 2005 step by step.
The example in the the book is based on Queue which store object just the
same as ArrayList does.
Here is a translation from Swedish to English. In some places the text say
it will cause compile error and in other places
say that no compiler error will be given but only run time exception.
In some places have I noticed that the text is completely wrong ?
Here start the translated text
"Because methods Enqueue and Dequeue both work with object they can be used
in connection with queue of type
Circle, PhoneBook Clock and other types. It's important to notice that the
value which is returned by method Dequeue must be
converted to a suitable value because the compiler will not automatically
convert from type object. If the returned value
is not type convered as in the example below will a compile error exist with
message "cannot implicitely convert type object to
Circle".
Circle myCircle = new Circle();
myQueue.Enqueue(myCircle);
...
myCircle = (Circle)myQueue.Dequeue(); // Type convert is mandatory
This kind of explicit type convert will remove most of the flexibility that
the object type has.
It's far to easy to write code like this.
Queue myQueue = new Queue();
Circle myCircle = new Circle();
...
Clock myClock = (Clock)myQueue.Dequeue();
Even if this code can be compiled it's not valid and will throw an exception
of type
System.InvalidCastException when the program is running.
The error is caused by trying to reference to a Circle in a variable of type
Clock
These two types is not compatible. The error will not be detected until run
time because the compiler doesn't have enough
information. The compiler can only decide the type of the object when taken
from the queue when the program is running."
//Tony
>> So you mean that a compile error will always be given when assigning an
>> object to for example a Person like this
[quoted text clipped - 18 lines]
> If the book actually says that, then it is wrong. Could you quote the
> actual text of the book?
Jon Skeet [C# MVP] - 28 Feb 2008 20:29 GMT
> The book is called Microsoft Visual C# 2005 step by step.
> The example in the the book is based on Queue which store object just the
[quoted text clipped - 3 lines]
> say that no compiler error will be given but only run time exception.
> In some places have I noticed that the text is completely wrong ?
It looks okay to me, although the second code bit should enqueue the
circle.
Which bit do you think is specifically wrong?

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Tony Johansson - 28 Feb 2008 20:53 GMT
Hello!
I mixed up two different things in the text.
There is no wrong text any more because you informed me with this text in
your mail
> So when will this InvalidCastException be given ?
If you do:
Person pp = (Person) arrList[0];
but actually arrList[0] isn't a Person, you'll get an
InvalidCastException.
//Tony
>> The book is called Microsoft Visual C# 2005 step by step.
>> The example in the the book is based on Queue which store object just the
[quoted text clipped - 9 lines]
>
> Which bit do you think is specifically wrong?
Jon Skeet [C# MVP] - 28 Feb 2008 20:55 GMT
> I mixed up two different things in the text.
> There is no wrong text any more because you informed me with this text in
> your mail
Goodo :)

Signature
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
World class .NET training in the UK: http://iterativetraining.co.uk
Tom P. - 28 Feb 2008 20:30 GMT
On Feb 28, 2:15 pm, "Tony Johansson" <johansson.anders...@telia.com>
wrote:
> Hello!
>
[quoted text clipped - 68 lines]
> >http://www.pobox.com/~skeet Blog:http://www.msmvps.com/jon.skeet
> > World class .NET training in the UK:http://iterativetraining.co.uk
This looks like a perfect example of what Jon was saying: If you only
put (Circle) objects in the Queue then the cast is a technicallity to
us since we know all the "Objects" are really "Circles".
BUT if you put more than one kind of object (say a Circle and two
Clocks) in the queue then be careful when you dequeue because if you
dequeue a Clock into a Circle type variable you'll get an
InvalidCastException.
Look the text over again and you'll see that the examples that compile
always have a cast, what the author is saying is be careful that you
are casting them correctly because the compiler can't tell what will
eventually end up in the queue.
Tom P.
Peter Duniho - 28 Feb 2008 21:03 GMT
> The book is called Microsoft Visual C# 2005 step by step.
> The example in the the book is based on Queue which store object just the
[quoted text clipped - 4 lines]
> say that no compiler error will be given but only run time exception.
> In some places have I noticed that the text is completely wrong ?
You should post those examples then, as you didn't post any text that was
wrong.
In the text, where it says a compile error will occur, it's talking about
trying to assign an instance of "Object" to an instance of something
else. And it's correct...without an explicit cast, a compiler error will
occur.
Where is says no compile error will occur, it's talking about what happens
once you _do_ use an explicit cast. This is an entirely different
situation, and is completely consistent with the text's previous statement
that an explicit cast is required to avoid a compile error. It goes on to
explain that if in fact the type is not the correct type in the collection
(as would be the case if you've added a Circle to the collection but then
tried to cast that to a Clock), you would get an error _but only at
run-time_. That's also correct.
A simpler example would be something like this:
Circle circle = new Circle();
Object obj = circle;
Clock clock = (Clock)obj;
The compiler is perfectly happy to compile that. But at run-time you are
guaranteed to fail with an invalid cast exception. This is the error that
the text is warning you against.
Basically, the text you did post doesn't say what you said it says, and it
is in fact correct.
The text you posted specifically says that because the Queue.Dequeue()
method returns an object, you must cast it. For the Queue class it's
talking about, it's exactly correct. Even the discussion regarding the
risks of doing that is correct. That is, when using the non-generic Queue
class, just as with the ArrayList, there's nothing to protect you at
compile time against putting the wrong type in the collection, or
incorrectly casting an instance retrieved from the collection.
If you want compile-time protection, you should use the generic classes
Queue<T> and List<T>. With those, you specify the type contained in the
collection when you declare the collection instance, and no casting is
necessary when retrieving instances from the collection, and trying to
retrieve something into the wrong type will generate a compiler error. In
addition, because adding to the collections is also typed more
specifically than "Object", the compiler will only let you add things of
the correct type to the collection.
Pete
Ben Voigt [C++ MVP] - 06 Mar 2008 20:39 GMT
> Hello!
>
> The book is called Microsoft Visual C# 2005 step by step.
> The example in the the book is based on Queue which store object just the
> same as ArrayList does.
No book covering 2005 should be using the untyped collections. We have
List<T> and Stack<T> for a reason.