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# / July 2007

Tip: Looking for answers? Try searching our database.

newbie trouble making array of instances

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
luke - 30 Jul 2007 10:30 GMT
I have a class 'item'  and I want to create an array of these items.

like this

ArrayList items = new ArrayList();
while (reader.read())
{
 item i = new item(Convert.ToString(reader[0]));
 items.Add(i);
}

But the address of item (&item) is the same for each pass of the
loop.  Consequentially every reference in the array is the same and
every item in my array displays the value of the last item set - which
makes sense considering all the references point to the same memory
location.  Ideally I'd like to have an array of unique items.  How do
I get a fresh instance on each pass of the loop?

Maybe I haven't had sleep enough?  Usually I program in C++.

TIA
Luke
Göran Andersson - 30 Jul 2007 10:50 GMT
> I have a class 'item'  and I want to create an array of these items.
>
[quoted text clipped - 18 lines]
> TIA
> Luke

The code that you have shown _does_ create a new item in each iteration
of the loop.

&item is not the address of the item that you have created, &i is.

Signature

Göran Andersson
_____
http://www.guffa.com

luke - 30 Jul 2007 12:47 GMT
On Jul 30, 7:50 pm, G?ran Andersson <gu...@guffa.com> wrote:
> > I have a class 'item'  and I want to create an array of these items.
>
[quoted text clipped - 27 lines]
> G?ran Andersson
> _____http://www.guffa.com

Thanks G?ran - I meant &i
Alberto Poblacion - 30 Jul 2007 10:53 GMT
>I have a class 'item'  and I want to create an array of these items.
>
[quoted text clipped - 9 lines]
> But the address of item (&item) is the same for each pass of the
> loop.

  Well, "item" is a class (not an instance), so it should have a fixed
address. I think that you mean &i, not &item. But the variable i can still
have the same adress for every pass of the loop, since it is a local
variable in the stack. Since you usually program in C++, think of i as a
pointer (that is, in C++ terms, i would be an item*, even though in C# you
just declare it as "item" instead of "item*"). The pointer has a fixed
address, even if the content of the pointer (the address to which it points)
is different for every iteration. Or in C++ terms, &i is constant even
though *i varies.

> Consequentially every reference in the array is the same and
> every item in my array displays the value of the last item set - which
> makes sense considering all the references point to the same memory
> location.  Ideally I'd like to have an array of unique items.  How do
> I get a fresh instance on each pass of the loop?

   It should be working the way you describe. The only reason why you
wouldn't be getting a different item on each iteration of the loop is if the
call to "new item" is always returning the same reference. Take a look at
what you are returning from the constructor in the item class.

> Maybe I haven't had sleep enough?  Usually I program in C++.
Göran Andersson - 30 Jul 2007 11:12 GMT
> The only reason why you
> wouldn't be getting a different item on each iteration of the loop is if
> the call to "new item" is always returning the same reference. Take a
> look at what you are returning from the constructor in the item class.

When using the new keyword, you always get a new instance. The instance
is created before the code in the constructor is executed, the
constructor doesn't return the instance.

Signature

Göran Andersson
_____
http://www.guffa.com

Jon Skeet [C# MVP] - 30 Jul 2007 11:19 GMT
On Jul 30, 11:12 am, G?ran Andersson <gu...@guffa.com> wrote:
> > The only reason why you
> > wouldn't be getting a different item on each iteration of the loop is if
> > the call to "new item" is always returning the same reference. Take a
> > look at what you are returning from the constructor in the item class.
>
> When using the new keyword, you always get a new instance.

<trivia>
Nearly, at least. There's an oddity with the string class is you pass
in an empty array of chars:

using System;

class Test
{
   static void Main(string[] args)
   {
     string x = new string(new char[]{});
     string y = new string(new char[]{});
     Console.WriteLine(object.ReferenceEquals(x,y));
   }
}
</trivia>

But that's the only example I know of :)

Jon
Peter Duniho - 30 Jul 2007 17:38 GMT
> Nearly, at least. There's an oddity with the string class is you pass
> in an empty array of chars:
[quoted text clipped - 13 lines]
>
> But that's the only example I know of :)

Speaking of that, I did a quick test the other day that was similar to
the above, except that it used empty strings instead.

Something like:

    string str1 = "test string";
    string str2 = "";
    string str3 = string.Empty;

    str1 = str1.Remove(0, str1.Length);

The references didn't wind up equal.  Particularly surprising was that
"" is not reference equal to string.Empty.  I wasn't really all that
surprised that str1 didn't wind up equal to anything else, but I was
surprised that str2 and str3 weren't equal references.

Given that you do get the same results passing different empty char[]
instances, why aren't these other cases doing the same thing?  Any ideas?

Pete
G.Doten - 30 Jul 2007 18:07 GMT
>> Nearly, at least. There's an oddity with the string class is you pass
>> in an empty array of chars:
[quoted text clipped - 8 lines]
>>       string y = new string(new char[]{});
>>       Console.WriteLine(object.ReferenceEquals(x,y));

I believe that these instances are the same because of this comment in
the documentation for the char[] constructor: "If value is a null
reference or contains no element, an Empty instance is initialized." So
your code is the same as doing this:

string x = string.Empty;
string y = string.Empty;

>>     }
>> }
[quoted text clipped - 17 lines]
> surprised that str1 didn't wind up equal to anything else, but I was
> surprised that str2 and str3 weren't equal references.

I believe that whenever you use '""' in a C# program, the compiler emits
a new instance for each of those quote pairs. Since string.Empty is
itself an instance of the string class then string.Empty does not refer
to the same instance as "".

Strings are immutable so when you did this:

str1 = str1.Remove(0, str1.Length);

The old instance of str1 was replaced with a whole new instance.

I don't remember the details off-hand, but the CLR also has special
built-in support for strings that no other object has. Or maybe it's
special IL instructions, I forget.

I have a FastString class that I found on the net somewhere years ago.
It uses unsafe code to mess with String objects "in place," must like
how you mess with strings in C/C++ by using the pointers. This code uses
string pointers in C#. I use this class very rarely and only when string
code must absolutely run faster.

> Given that you do get the same results passing different empty char[]
> instances, why aren't these other cases doing the same thing?  Any ideas?

See above. Make sense?

Signature

-glenn-

Peter Duniho - 30 Jul 2007 18:45 GMT
[...]
>> Given that you do get the same results passing different empty char[]
>> instances, why aren't these other cases doing the same thing?  Any ideas?
>
> See above. Make sense?

You didn't add anything, at least not with respect to my understanding.
 I already know what the behavior is, and I already understand all of
the details you wrote.  I was wondering if anyone had any insight as to
_why_ .NET is designed this way.

They special-case the empty-array so that the resulting strings are the
string.Empty instance.  Why not special-case other examples, such as
empty strings ("") and empty strings (str1.Remove(0, str1.Length))?

"" would be trivial to special-case, and would not incur any run-time
overhead (the compiler could do the mapping, and I would consider it a
particular instance of string pooling, something compilers usually do
anyway).  The Remove() case would incur some negligible amount of
run-time overhead, but not enough to warrant not doing IMHO (and in the
empty-string case, would actually be faster).

I could see never bothering to map empty strings to the special
string.Empty intance.  I could see always mapping empty strings to the
special string.Empty instance.  I don't understand why sometimes empty
strings are mapped to string.Empty and sometimes they aren't.

Pete
G.Doten - 30 Jul 2007 19:24 GMT
> [...]
> I was wondering if anyone had any insight as to
> _why_ .NET is designed this way.

As I said, because strings are immutable and are treated specially by
the run-time.

Signature

-glenn-

Peter Duniho - 30 Jul 2007 19:42 GMT
>> [...]
>> I was wondering if anyone had any insight as to _why_ .NET is designed
>> this way.
>
> As I said, because strings are immutable and are treated specially by
> the run-time.

That is not an explanation.
Jon Skeet [C# MVP] - 30 Jul 2007 18:51 GMT
> >>     static void Main(string[] args)
> >>     {
[quoted text clipped - 9 lines]
> string x = string.Empty;
> string y = string.Empty;

Well, that just says it's documented - it doesn't explain *how* it
happens. Calling a constructor should logically (and even according to
the C# spec) create a new object. You certainly can't create a C# class
which has this behaviour, for instance.

> > The references didn't wind up equal.  Particularly surprising was that
> > "" is not reference equal to string.Empty.  I wasn't really all that
[quoted text clipped - 5 lines]
> itself an instance of the string class then string.Empty does not refer
> to the same instance as "".

C# guarantees that all uses of the same string constant within an
assembly use the same object.

> Strings are immutable so when you did this:
>
> str1 = str1.Remove(0, str1.Length);
>
> The old instance of str1 was replaced with a whole new instance.

Well, the value of str1 was replaced with a reference to a different
instance. The string itself wasn't being replaced.

However String.Remove certainly *could* detect that the result was
going to be an empty string, and return string.Empty instead of
creating a new empty string.

Signature

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

G.Doten - 30 Jul 2007 19:31 GMT
>>>>     static void Main(string[] args)
>>>>     {
[quoted text clipped - 13 lines]
> the C# spec) create a new object. You certainly can't create a C# class
> which has this behaviour, for instance.

Sure you can. All the char[] constructor is doing is looking to see if
the passed-in char array is null or if it has 0 elements, in which case
it sets it's internal string storage to the string.Empty instance. Any
class can easily be written to do the same. Philosophically (so to
speak) why is the constructor implemented this way? I can't say for
sure, just guess that string.Empty is ever so slightly more efficient
than created a new instance of an empty string. Seems like a worthwhile
optimization to me.

>> Strings are immutable so when you did this:
>>
[quoted text clipped - 4 lines]
> Well, the value of str1 was replaced with a reference to a different
> instance. The string itself wasn't being replaced.

Well, yes, str1 is being replaced by a new string instance. The expression:

str1.Remove(0, str1.Length)

creates a new string object and it is this new instance that replaces
the old instance that str1 used to point to. Strings cannot be modified
in-place due to their immutable nature (unless unsafe code is used).

Signature

-glenn-

Peter Duniho - 30 Jul 2007 19:46 GMT
>> Well, that just says it's documented - it doesn't explain *how* it
>> happens. Calling a constructor should logically (and even according to
[quoted text clipped - 5 lines]
> it sets it's internal string storage to the string.Empty instance. Any
> class can easily be written to do the same.

Please post some sample code in which you can instantiate the same class
twice, using the "new" operator, in which the _references_ of both
instances are identical.

[...]
>>> Strings are immutable so when you did this:
>>>
[quoted text clipped - 6 lines]
>
> Well, yes, str1 is being replaced by a new string instance.

No.  The reference contained by the variable str1 is being replaced by a
new reference, which is what Jon wrote.  However, the original string is
not replaced.  For example:

    string str1, str2;

    str2 = "test string";
    str1 = str2;
    str1 = str1.Remove(0, str1.Length);

The original string "test string" still exists.  It was not replaced.  A
new string instance was created by the Remove() method, and the
reference to this new instance was assigned to str1.

None of this, however, explains why the Remove() method doesn't simply
return the string.Empty instance, rather than actually create a brand
new instance that happens to have data equivalent to string.Empty.

Pete
G.Doten - 30 Jul 2007 20:21 GMT
>>> Well, that just says it's documented - it doesn't explain *how* it
>>> happens. Calling a constructor should logically (and even according
[quoted text clipped - 9 lines]
> twice, using the "new" operator, in which the _references_ of both
> instances are identical.

I think you guys are right and I'm wrong on this one. At least I can't
get a class to do this (see my attempt below). I thought that
String.Intern would cause a single instance of my Empty field to be
created, but that doesn't seem to be the case, and I don't understand why.

The String class is integrated right into the CLR so that it knows the
exact layout of the class' fields (quoting Jeffrey Richter here), so I
bet if you look at the IL generated that there is special "string code"
that checks the one instance of the Empty field. But I'll admit I'm a
little puzzled on this one too.

>>>> Strings are immutable so when you did this:
>>>>
[quoted text clipped - 20 lines]
> new string instance was created by the Remove() method, and the
> reference to this new instance was assigned to str1.

I didn't say that the str2 was replaced or that str1's old string value
was replaced. Here's what Jon said:

> > Strings are immutable so when you did this:
> > >
> > > str1 = str1.Remove(0, str1.Length);
> > >
> > > The old instance of str1 was replaced with a whole new instance.

and I said:

> Well, the value of str1 was replaced with a reference to a different
> instance. The string itself wasn't being replaced.

Indeed, str1 is replaced by a new instance of a string object, the one
returned by the call to str1.Remove. And the reference to the string
that str1 used to point to is decremented by 1 so when it goes to 0 the
GC can have at it.

> None of this, however, explains why the Remove() method doesn't simply
> return the string.Empty instance, rather than actually create a brand
> new instance that happens to have data equivalent to string.Empty.

I see. I guess for the same reason that the char[] constructor behaves
the way it does, because it is documented to. This is in the Remove
documentation: "returns a new String that is equivalent to this instance
less count number of characters." Notice there is no verbiage describing
special-casing around a string that happens to come back as empty; it
says it *always* returns a new string. Which makes sense to me given the
immutable nature of strings. I don't think I'd want the Remove method to
have that special case, but I can see it's usefulness (in terms of
performance) for the char[] constructor.

-----------------------------------------------------------------

Here's the code I tried:

using System;

namespace MyStringTest
{
    class Program
    {
        static void Main()
        {
            MyString x = new MyString(new char[] { });
            MyString y = new MyString(new char[] { });
            Assert("case 1a", true, ReferenceEquals(x, y));
            Assert("case 1b", true, ReferenceEquals((object)x, (object)y));

            string s1 = new string(new char[] { });
            string s2 = new string(new char[] { });
            Assert("case2", true, ReferenceEquals(s1, s2));

            string s = "Hello";
            Assert("case2", true, ReferenceEquals("Hello", s));

            string h1 = "Hel";
            string h2 = "lo";
            Assert("case3a", false, ReferenceEquals("Hello", h1+h2));
            Assert("case3b", true, ReferenceEquals("Hello", string.Intern(h1+h2)));
        }

        static void Assert(string name, bool expected, bool actual)
        {
            Console.Write(name + " - ");
            Console.WriteLine(expected == actual ? "success" : "failure");
        }
    }

    public class MyString
    {
        public static readonly string Empty = string.Intern("");

        string _s;

        public MyString(char[] ch)
        {
            if (ch == null || ch.Length == 0)
                _s = Empty;
            else
                _s = new string(ch);
        }

        public bool IsEmpty
        {
            get
            {
                return _s == Empty;
            }
        }
    }
}

Signature

-glenn-

Peter Duniho - 30 Jul 2007 20:46 GMT
[...]
>> The original string "test string" still exists.  It was not replaced.  
>> A new string instance was created by the Remove() method, and the
>> reference to this new instance was assigned to str1.
>
> I didn't say that the str2 was replaced or that str1's old string value
> was replaced.

That is what you appeared to say.  Call it a semantic misunderstanding
if you like.

Here's what Jon said:

>  > > Strings are immutable so when you did this:
>  > > >
[quoted text clipped - 9 lines]
> Indeed, str1 is replaced by a new instance of a string object, the one
> returned by the call to str1.Remove.

Here you appear to say it again.  IMHO, it is worthwhile to be very
careful about the language you use.  The computer is very literal, and
so when talking about what the computer does, one should be very literal.

In particular: "str1" is a variable.  It's not replaced at all, so
writing "str1 is replaced" doesn't make sense.  There is a string to
which "str1" refers.  That's not replaced at all either.  There is a
reference value that is stored in "str1".  This _is_ replaced, by a new
and different reference value.

And the reference to the string
> that str1 used to point to is decremented by 1 so when it goes to 0 the
> GC can have at it.

C# garbage collection doesn't use reference counting, so even if you
meant "the count of references to the string that str1 used to point to"
(clearly the reference itself shouldn't be decremented), the statement
would be incorrect.

>> None of this, however, explains why the Remove() method doesn't simply
>> return the string.Empty instance, rather than actually create a brand
>> new instance that happens to have data equivalent to string.Empty.
>
> I see. I guess for the same reason that the char[] constructor behaves
> the way it does, because it is documented to.

I don't see that as a reason.  Things are documented to describe how
those things behave.  Saying that things behave in a particular way
_because_ they are documented to do so doesn't explain anything.

This is in the Remove
> documentation: "returns a new String that is equivalent to this instance
> less count number of characters." Notice there is no verbiage describing
> special-casing around a string that happens to come back as empty; it
> says it *always* returns a new string.

Again, that's simply the documentation describing what it does.  That
doesn't explain _why_ it does what it does.

Which makes sense to me given the
> immutable nature of strings. I don't think I'd want the Remove method to
> have that special case, but I can see it's usefulness (in terms of
> performance) for the char[] constructor.

Why and why not?  Why is it okay to special case the string(char[])
constructor, but not the Remove() method?  You get a memory performance
benefit out of both, at the (very tiny tiny) cost of execution performance.

> -----------------------------------------------------------------
>
> Here's the code I tried:

Your code doesn't do anything to attempt to change the reference
returned by the "new" operator.  All it does is ensure that each
instance of your MyString class contains a reference to a single "Empty"
string instance when possible.

The reference to the class itself is not at all the same as a reference
to some member of the class.

Pete
G.Doten - 30 Jul 2007 21:07 GMT
> [...]
>>> The original string "test string" still exists.  It was not
[quoted text clipped - 6 lines]
> That is what you appeared to say.  Call it a semantic misunderstanding
> if you like.

Fair enough.

> Here's what Jon said:
>>
[quoted text clipped - 21 lines]
> reference value that is stored in "str1".  This _is_ replaced, by a new
> and different reference value.

I believe we are saying the same thing. I fully understand that str1 is
a reference to a string but the places I work "str1 is replaced," in the
context I said it, would be normal parlance for the more accurate
terminology "the reference in str1 is replaced with a value (reference)
that points to a different string instance." That's what I meant so,
again, we mean the same thing, I just wasn't being pedantic when I said
it. But as you rightly point out, that can lead to technical
miscommunication.

 >
> And the reference to the string
>> that str1 used to point to is decremented by 1 so when it goes to 0
[quoted text clipped - 4 lines]
> (clearly the reference itself shouldn't be decremented), the statement
> would be incorrect.

You are absolutely correct. My point was that once there are no more
references to the instance of the string that str1 was originally
pointing to (as in Jon's example), the GC will be able to collect that
string (assuming no nothing else has a reference to it).

>>> None of this, however, explains why the Remove() method doesn't
>>> simply return the string.Empty instance, rather than actually create
[quoted text clipped - 25 lines]
> constructor, but not the Remove() method?  You get a memory performance
> benefit out of both, at the (very tiny tiny) cost of execution performance.

I guess I just don't understand the distinction here. Are you looking
for some sort of "philosophical" reason why the BCL writers decided to
write these two methods like that? Because otherwise these behaviors are
nothing more than implementation details, and they just are what they
are. To me the behavior makes sense (or at least it doesn't make me ask,
"huh?"). If Remove special-cased null/empty and returned Empty in such a
case I think, as far as I understand what you are asking, that you would
have just as legitimate a question. So I think I'm being thick here, to
be honest.

>> -----------------------------------------------------------------
>>
[quoted text clipped - 7 lines]
> The reference to the class itself is not at all the same as a reference
> to some member of the class.

Yes, you are correct again. That dawned on me after playing around with
the code some more; I was barking up the wrong tree. Again, the CLR has
special knowledge of the actual fields within a String object and that
has got to be how it does it's magic allowing what you would normally
think are two separate instances of a string (because all the other
objects behave that way) to be the very same instance.

My understanding is that these special String hooks in the CLR are
totally for enhanced performance of strings. I think you just have to be
aware of this special behavior of strings when working with them and
that no other object behaves this way (AFAIK).

Signature

-glenn-

Peter Duniho - 30 Jul 2007 21:22 GMT
[...]
> I guess I just don't understand the distinction here. Are you looking
> for some sort of "philosophical" reason why the BCL writers decided to
> write these two methods like that?

Essentially, yes.

Because otherwise these behaviors are
> nothing more than implementation details, and they just are what they
> are.

That's fine, but it still doesn't explain the _reason_ behind why they
are what they are.

To me the behavior makes sense (or at least it doesn't make me ask,
> "huh?"). If Remove special-cased null/empty and returned Empty in such a
> case I think, as far as I understand what you are asking, that you would
> have just as legitimate a question.

Yes, I could still ask the question "why?".  You can always ask the
question "why?"  But I would be more inclined to be able to infer an
answer to that question if the behavior were always consistent.  That
is, if the string class always converted empty strings to the single
empty instance, or if it never did.

The fact that sometimes it does and sometimes it doesn't is what raises
the question for me.  So far, no one's offered an explanation, so
perhaps there isn't one.  Sometimes, things are inconsistent due to
simple lack of consideration on the part of the designer.

But sometimes the designer is aware of the inconsistency, but lives with
it because of some other issue that is less obvious.

Pete
Jon Skeet [C# MVP] - 30 Jul 2007 21:52 GMT
> > Well, that just says it's documented - it doesn't explain *how* it
> > happens. Calling a constructor should logically (and even according to
[quoted text clipped - 4 lines]
> the passed-in char array is null or if it has 0 elements, in which case
> it sets it's internal string storage to the string.Empty instance.

No, that's not what it's doing. It's a constructor *to String* which
isn't returning a reference to a new object. That defies the C# spec
which states:

<quote>
The new operator implies creation of an instance of a type, but does
not necessarily imply dynamic allocation of memory.
</quote>

(The latter part is for value types, basically.)

In this case, the string constructor is *not* creating a new instance
of string.

> Any class can easily be written to do the same.

No, it can't.

> >> Strings are immutable so when you did this:
> >>
[quoted text clipped - 6 lines]
>
> Well, yes, str1 is being replaced by a new string instance.

No. str1 isn't a string. It's a reference to a string.

> The expression:
>
> str1.Remove(0, str1.Length)
>
> creates a new string object and it is this new instance that replaces
> the old instance that str1 used to point to.

No, it's the *reference* to the new string that replaces the previous
value of str1. It's not a case of one string *instance* replacing
another.

> Strings cannot be modified
> in-place due to their immutable nature (unless unsafe code is used).

Indeed, and that doesn't go against what I was saying.

Signature

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

Jon Skeet [C# MVP] - 30 Jul 2007 18:46 GMT
> Speaking of that, I did a quick test the other day that was similar to
> the above, except that it used empty strings instead.
[quoted text clipped - 14 lines]
> Given that you do get the same results passing different empty char[]
> instances, why aren't these other cases doing the same thing?  Any ideas?

I think it depends on the pool of literals being used. I don't know the
exact details of how literals all work - I *think* there's one string
literal pool per AppDomain, and it's possible that there's a separate
one for domain-neutral assemblies. Or I could be talking rubbish :)

Signature

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

Alberto Poblacion - 30 Jul 2007 11:20 GMT
>> The only reason why you wouldn't be getting a different item on each
>> iteration of the loop is if the call to "new item" is always returning
[quoted text clipped - 4 lines]
> created before the code in the constructor is executed, the constructor
> doesn't return the instance.

   Oops... Sorry! I don't know what I was thinking. Or rather, yes, I know
what I was thinking: the Singleton pattern, where you always get the same
instance... but you get it from a function, not from the constructor. Sorry
about the hasty answer.
luke - 30 Jul 2007 13:00 GMT
On Jul 30, 8:20 pm, "Alberto Poblacion" <earthling-
quitaestoparacontes...@poblacion.org> wrote:
> "G?ran Andersson" <gu...@guffa.com> wrote in message
>
[quoted text clipped - 13 lines]
> instance... but you get it from a function, not from the constructor. Sorry
> about the hasty answer.

Oh now I've got no hope.   I might have been returning the address of
the pointer but that was my only explanation for why updating any item
in the array updates all items.   And I was kinda hoping I knew so
little about C# that I was just messing up my constructor.  I suppose
I'll post my actual code tomorrow and see if anyone can spot my dumb
mistake.  Thanks everyone.  Glad to know that I'm not too far off
track and that C# isn't as esoteric as I was beginning to fear.
luke - 31 Jul 2007 04:45 GMT
> On Jul 30, 8:20 pm, "Alberto Poblacion" <earthling-
>
[quoted text clipped - 24 lines]
> mistake.  Thanks everyone.  Glad to know that I'm not too far off
> track and that C# isn't as esoteric as I was beginning to fear.

I woke this morning and without looking at my code I new what I'd
done.   I'd declared all the member variables of 'item' static.  I
don't know why - retarded moment. Sorry for wasting your time.  I
learned about posting short working code though.  Thanks Jon.

I was thrown by the reference to each 'item' being the same.  Had the
watch window displayed address for 'item' rather than contents of item
I'd not been compelled to use &item.  I tried *item and that seems to
show the address - does this mean show item as a pointer?

Thanks All.
Göran Andersson - 31 Jul 2007 19:41 GMT
> I woke this morning and without looking at my code I new what I'd
> done.   I'd declared all the member variables of 'item' static.

So you had separate instances of the class, but none of them contain any
data at all. :)

> I
> don't know why - retarded moment. Sorry for wasting your time.  I
[quoted text clipped - 4 lines]
> I'd not been compelled to use &item.  I tried *item and that seems to
> show the address - does this mean show item as a pointer?

A reference is a pointer, but the syntax when you use a reference is
different from using a pointer.

The & operator gives you the address of the variable, i.e. the address
of the pointer. If the reference is a local variable, this is an address
inside the stack frame for the method.

The * operator dereferences the reference and gives you the value of the
variable, which is the address of the object.

In your code, &i gives you the address of the local variable i, which of
course is the same regardless of what the variable contains.

Signature

Göran Andersson
_____
http://www.guffa.com

luke - 30 Jul 2007 12:51 GMT
On Jul 30, 7:53 pm, "Alberto Poblacion" <earthling-
quitaestoparacontes...@poblacion.org> wrote:

> >I have a class 'item'  and I want to create an array of these items.
>
[quoted text clipped - 32 lines]
>
> > Maybe I haven't had sleep enough?  Usually I program in C++.

Oh so 'i' is like a pointer and I am returning the address of the
pointer...  In my watch window, if I don't use the ampersand it shows
the contents of my class.  How do I get the value stored in the
pointer?

I don't think I'm returning anything from my constructor - it just
sets a bunch of vars.
Jon Skeet [C# MVP] - 30 Jul 2007 11:19 GMT
> I have a class 'item'  and I want to create an array of these items.

<snip>

As others have said, it should be working okay.

Could you post a short but complete program which demonstrates the
problem?
See http://pobox.com/~skeet/csharp/complete.html

Jon
luke - 30 Jul 2007 12:52 GMT
> > I have a class 'item'  and I want to create an array of these items.
>
[quoted text clipped - 7 lines]
>
> Jon

Will do - after I get some sleep, thanks Jon

Rate this thread:







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.