Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / March 2008

Tip: Looking for answers? Try searching our database.

using ArrayList with object

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Tony Johansson - 28 Feb 2008 19:00 GMT
Hello!

The question is about this assignment statement Person pp = arrList[0];
I know that to correct the error I have to write Person pp =
(Person)arrList[0];

But my question is the following.
This statement give compile error. I have always thought that the compiler
doesn't see these kind of error which
therefore only give run time error of type InvalidCastException.

I'm I wrong in some way. I have even read this in some books that the
compiler only see the type when
taken from the collection and assigning to a new object type.

class Program
   {
       ArrayList arrList = new ArrayList();

       public Program()
       {
           arrList.Add(new Person("123456-1234", "Nisse", 14));
           arrList.Add(new Person("987654-4321", "Pelle", 15));
           arrList.Add(new Person("563423-7612", "Stina", 35));

           Person pp = arrList[0];
       }

       static void Main(string[] args)
       {
           Program prog = new Program();
       }
   }

   class Person
   {
       private string pers_nr;
       private string name;
       private int age;

       public Person(string pers_nr, string name, int age)
       {
           this.pers_nr = pers_nr;
           this.name = name;
           this.age = age;
       }

       public string Pers_nr
       {
           get { return pers_nr; }
           set { pers_nr = value; }
       }

       public string Name
       {
           get { return name; }
           set { name = value; }
       }

       public int Age
       {
           get { return age; }
           set { age = value; }
       }

       public override string ToString()
       {
           return string.Format("Pers_nr = {0} Name = {1} Age = {2}",
               Pers_nr, Name, Age);
       }
   }

//Tony
Peter Duniho - 28 Feb 2008 19:07 GMT
> Hello!
>
> The question is about this assignment statement Person pp = arrList[0];
> I know that to correct the error I have to write Person pp =
> (Person)arrList[0];

That's right.  ArrayList returns an object, so you have to cast back to  
the original type.

> But my question is the following.
> This statement give compile error.

Which statement?  The code you posted doesn't have a cast, so yes...you'll  
get a compiler error.

Do you have an example where you _are_ doing the cast, and yet still get  
an error?

Pete
Tony Johansson - 28 Feb 2008 19:15 GMT
Hello!

So you mean that a compile error will always be given when assigning an
object to for example a Person like this
Person pp = arrList[0];
So when will this InvalidCastException be given ?

So what the book was writing telling me that this statement Person pp =
arrList[0];
will compile but give a run time error of type InvalidCastException  is
completely wrong.

//Tony

On Thu, 28 Feb 2008 11:00:02 -0800, Tony Johansson
<johansson.andersson@telia.com> wrote:

> Hello!
>
> The question is about this assignment statement Person pp = arrList[0];
> I know that to correct the error I have to write Person pp =
> (Person)arrList[0];

That's right.  ArrayList returns an object, so you have to cast back to
the original type.

> But my question is the following.
> This statement give compile error.

Which statement?  The code you posted doesn't have a cast, so yes...you'll
get a compiler error.

Do you have an example where you _are_ doing the cast, and yet still get
an error?

Pete
Jon Skeet [C# MVP] - 28 Feb 2008 19:24 GMT
> So you mean that a compile error will always be given when assigning an
> object to for example a Person like this
> Person pp = arrList[0];

Yes.

> 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.

> So what the book was writing telling me that this statement Person pp =
> arrList[0];
> will compile but give a run time error of type InvalidCastException  is
> completely wrong.

If the book actually says that, then it is wrong. Could you quote the
actual text of the book?

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:15 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.
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.
Phil Wilson - 28 Feb 2008 20:47 GMT
If the book also covers generic collections then you might find that
sometimes List <Person> is the kind of thing you want to use.
Signature

Phil Wilson
[MVP Windows Installer]

> Hello!
>
[quoted text clipped - 32 lines]
>
> Pete

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.