referencing a value...

D

Dan Bass

Say I've got an ArrayList, which contains a list of integers.
Is it possible to get a reference to one of the integers contained within
the collection so that changes to it are reflected in the arraylist?



Eg... For references.

Class myClass
{
public myClass ( string initialValue )
{
_myString = initialValue;
}

private string _myString = "Hello";
public string MyString
{
// get/set here exposing myString
}
}

// inside a method
ArrayList myClassArray = new ArrayList();
myClassArray.Add ( new myClass("Good") );
myClassArray.Add ( new myClass("Better") );
myClassArray.Add ( new myClass("Fantastic") );

foreach ( myClass currentInstance in myClassArray )
{
// this is a reference to each instance of myClass
// therefore all the _myStrings will contain this in
// the ArrayList
currentInstance.MyString = "Not Too Good";
}


Eg.. for values

ArrayList myIntArray = new ArrayList ();
myIntArray.Add ( 1 );
myIntArray.Add ( 2 );
myIntArray.Add ( 3 );

foreach ( int x in myIntArray )
{
// not a reference because int is value
// QUESTION: how do i get a reference
// to each int without referencing it
// like this: myIntArray[z] = ...
x = 5;
}
 
D

Dan Bass

Never mind...

MSDN: "Value types are always accessed directly; it is not possible to
create a reference to a value type"
 
M

Manohar Kamath

You could contain the int value within a wrapper object, and hold reference
to that object.

E.g.

public class IntWrap
{
private int _myInt;

public int myInt
{
get {...}
set {...}
}
}

--
Manohar Kamath
Editor, .netWire
www.dotnetwire.com


Dan Bass said:
Never mind...

MSDN: "Value types are always accessed directly; it is not possible to
create a reference to a value type"

Dan Bass said:
Say I've got an ArrayList, which contains a list of integers.
Is it possible to get a reference to one of the integers contained within
the collection so that changes to it are reflected in the arraylist?



Eg... For references.

Class myClass
{
public myClass ( string initialValue )
{
_myString = initialValue;
}

private string _myString = "Hello";
public string MyString
{
// get/set here exposing myString
}
}

// inside a method
ArrayList myClassArray = new ArrayList();
myClassArray.Add ( new myClass("Good") );
myClassArray.Add ( new myClass("Better") );
myClassArray.Add ( new myClass("Fantastic") );

foreach ( myClass currentInstance in myClassArray )
{
// this is a reference to each instance of myClass
// therefore all the _myStrings will contain this in
// the ArrayList
currentInstance.MyString = "Not Too Good";
}


Eg.. for values

ArrayList myIntArray = new ArrayList ();
myIntArray.Add ( 1 );
myIntArray.Add ( 2 );
myIntArray.Add ( 3 );

foreach ( int x in myIntArray )
{
// not a reference because int is value
// QUESTION: how do i get a reference
// to each int without referencing it
// like this: myIntArray[z] = ...
x = 5;
}
 
D

Dan Bass

Thanks for that. The reason for my initial question is I'm using structs in
an ArrayList and I wanted to see if I could shorten

((MyStructure)myArrayList[ x ]).Variable = ...



Manohar Kamath said:
You could contain the int value within a wrapper object, and hold
reference
to that object.

E.g.

public class IntWrap
{
private int _myInt;

public int myInt
{
get {...}
set {...}
}
}

--
Manohar Kamath
Editor, .netWire
www.dotnetwire.com


Dan Bass said:
Never mind...

MSDN: "Value types are always accessed directly; it is not possible to
create a reference to a value type"

"Dan Bass" <danielbass [at] postmaster [dot] co [dot] uk> wrote in
message
Say I've got an ArrayList, which contains a list of integers.
Is it possible to get a reference to one of the integers contained within
the collection so that changes to it are reflected in the arraylist?



Eg... For references.

Class myClass
{
public myClass ( string initialValue )
{
_myString = initialValue;
}

private string _myString = "Hello";
public string MyString
{
// get/set here exposing myString
}
}

// inside a method
ArrayList myClassArray = new ArrayList();
myClassArray.Add ( new myClass("Good") );
myClassArray.Add ( new myClass("Better") );
myClassArray.Add ( new myClass("Fantastic") );

foreach ( myClass currentInstance in myClassArray )
{
// this is a reference to each instance of myClass
// therefore all the _myStrings will contain this in
// the ArrayList
currentInstance.MyString = "Not Too Good";
}


Eg.. for values

ArrayList myIntArray = new ArrayList ();
myIntArray.Add ( 1 );
myIntArray.Add ( 2 );
myIntArray.Add ( 3 );

foreach ( int x in myIntArray )
{
// not a reference because int is value
// QUESTION: how do i get a reference
// to each int without referencing it
// like this: myIntArray[z] = ...
x = 5;
}
 
D

Dan Bass

This doesn't even work. Which means I have to do:

MyStructure currentStructure = (MyStructure)myArrayList[ x ];

// ... a few changes to currentStructure here

myArrayList.RemoveAt(x);
myArrayList.Insert(x, currentStructure);


Not pretty...

Dan Bass said:
Thanks for that. The reason for my initial question is I'm using structs
in an ArrayList and I wanted to see if I could shorten

((MyStructure)myArrayList[ x ]).Variable = ...



Manohar Kamath said:
You could contain the int value within a wrapper object, and hold
reference
to that object.

E.g.

public class IntWrap
{
private int _myInt;

public int myInt
{
get {...}
set {...}
}
}

--
Manohar Kamath
Editor, .netWire
www.dotnetwire.com


"Dan Bass" <danielbass [at] postmaster [dot] co [dot] uk> wrote in
message
Never mind...

MSDN: "Value types are always accessed directly; it is not possible to
create a reference to a value type"

"Dan Bass" <danielbass [at] postmaster [dot] co [dot] uk> wrote in
message
Say I've got an ArrayList, which contains a list of integers.
Is it possible to get a reference to one of the integers contained within
the collection so that changes to it are reflected in the arraylist?



Eg... For references.

Class myClass
{
public myClass ( string initialValue )
{
_myString = initialValue;
}

private string _myString = "Hello";
public string MyString
{
// get/set here exposing myString
}
}

// inside a method
ArrayList myClassArray = new ArrayList();
myClassArray.Add ( new myClass("Good") );
myClassArray.Add ( new myClass("Better") );
myClassArray.Add ( new myClass("Fantastic") );

foreach ( myClass currentInstance in myClassArray )
{
// this is a reference to each instance of myClass
// therefore all the _myStrings will contain this in
// the ArrayList
currentInstance.MyString = "Not Too Good";
}


Eg.. for values

ArrayList myIntArray = new ArrayList ();
myIntArray.Add ( 1 );
myIntArray.Add ( 2 );
myIntArray.Add ( 3 );

foreach ( int x in myIntArray )
{
// not a reference because int is value
// QUESTION: how do i get a reference
// to each int without referencing it
// like this: myIntArray[z] = ...
x = 5;
}
 
J

Jon Skeet [C# MVP]

This doesn't even work. Which means I have to do:

MyStructure currentStructure = (MyStructure)myArrayList[ x ];

// ... a few changes to currentStructure here

myArrayList.RemoveAt(x);
myArrayList.Insert(x, currentStructure);

No, you do:

MyStructure currentStructure = (MyStructure) myArrayList[x];
// Make some changes...
myArrayList[x] = currentStructure;

You *can* get round this using interfaces - if you create an interface
with an appropriate "set" method, and make your value type implement
that method, the boxed type implements it as well and acts on the boxed
value. It's not a good idea in terms of code readability though.
 
B

Bruce Wood

A lot of this comes down to the decision to use structs in the first
place.

A lot of ex-C programmers (like me) think, "Hey, I don't need all that
class overhead... I'll use a struct, which is more lightweight," and
then we get ourselves into a world of trouble as a result.

More knowledgeable posters like Jon can correct me of I'm wrong, but my
(current) guide for using structs versus classes (after much pain) is
as follows:

A struct in .NET is a new primitive value type, like an int or a
double. If the thing you're making doesn't fit into the category of
"fundamental data type" then it probably wants to be a class, not a
struct.

For example, one of the few structs I've built is a Fraction class.
Complex numbers are nother good candidate.

Although you can write a struct so that it is mutable, it's generally a
bad idea... generally an indication that you want a class, not a
struct. A method of a struct that "changes" the struct should return a
new copy rather than changing the original, just as the String methods
do.

structs in .NET are _not_ just "lighter weight classes". They have very
different semantics from those of classes. Although you can twist the
language around to create a struct that acts sort of like a
lightweight, mutable class, it's an abuse of .NET and will come back to
haunt you in so many ways it's just not worth it.

Dan, I'm not saying that this is what you're doing... just passing
along what I've learned from the pain of doing things the "wrong way."
:)
 
D

Dan Bass

why have "out" when you have "ref"? [parameters]
why have "struct" when you have "class"?
why have "readonly" when you could widen the scope of "const"?

a struct to me (correct me please!) is when you want to contain a view data
members with no real methods, not much inheritence hierarchy. In this case
I've written an application that is a message router. There's an inbound
interface, router, and outbound interface. I used struct to define what
properties are contained with in each of these three components.

Should I use classes?

Cheers for the feedback... [ I'm an ex-C++ where everything was value until
you had a * or &, but taken to c# like a duck to water ]
 
J

Jon Skeet [C# MVP]

why have "out" when you have "ref"? [parameters]

out and ref have different semantics in terms of definite assignment.
If you make a parameter "out" rather than "ref" it makes it very clear
that the method won't use any initial value of the parameter.
why have "struct" when you have "class"?

Because sometimes you want value semantics rather than reference type
semantics.
why have "readonly" when you could widen the scope of "const"?

The two are slightly different - const values are "baked into" the
class, and must therefore be compile-time constants.
a struct to me (correct me please!) is when you want to contain a view data
members with no real methods, not much inheritence hierarchy.

You can have perfectly good methods in a value type to me - look at
DateTime, for example.
In this case
I've written an application that is a message router. There's an inbound
interface, router, and outbound interface. I used struct to define what
properties are contained with in each of these three components.

Should I use classes?

It's hard to say for sure, but quite possibly. I use classes for almost
everything, unless I've got a very definite reason to use a struct
instead.
 
B

Bruce Wood

a struct to me (correct me please!) is when you want to contain a
view data
members with no real methods, not much inheritence hierarchy.

No, not in C#. The reason for choosing a struct over a class in C# is
that you want _value semantics_ instead of _reference semantics_. In
other words, you want the thing to be immutable, and operations on it
create a new copy rather than changing the thing itself. To choose a
silly example:

int i = 3;
i += 15;

in this case, you want i contain a _value_ 3, not a _reference_ to 3,
and you want the second line to compute a new value, 18, and place that
in i, not change the literal 3 to now mean 18, which would be bad. :)
You can use structs in C# to reproduce this same behaviour: you can
create a Fraction struct that is immutable, and every operation on a
Fraction creates a new Fraction with a new value. Whenever it is
passed-by-value as an argument, it is copied. Whenever it is assigned
from one variable to another, it is copied, just like an int or a
double.

If you want an object that acts like a class instance but doesn't have
any methods or properties, just fields, and doesn't inherit from
anything, create exactly that: a class with only public fields. If you
want nothing to be able to inherit from it, declare it "sealed".

Of course, FxCop complains that this is bad practice: you really should
hide the fields behind properties. I usually do this (because I'm a
pedantic sort), and then later discover that yes, this class really
does have some business logic behind it, and I end up writing beefier
properties and maybe even a method or two later on. Seems as though the
C# designers are smarter than I am. :)

So, the bottom line is that in C#, you use classes unless you really
want value behaviour as described above.

P.S.: I learned all of this by doing it the wrong way first (also being
an old C/C++ hack).
 
J

Jon Skeet [C# MVP]

Bruce Wood said:
No, not in C#. The reason for choosing a struct over a class in C# is
that you want _value semantics_ instead of _reference semantics_. In
other words, you want the thing to be immutable, and operations on it
create a new copy rather than changing the thing itself.

Hang on - there's nothing to say that a value type *has* to be
immutable, or that a reference type has to be mutable.

Value semantics vs reference semantics often touch on immutability, but
there's nothing which forces it.

<snip>
 
B

Bruce Wood

True. I'm sorry if my post implied that value types _have_ to be
immutable. However, you must admit that if you have a mutable value
type then you're skating on thin ice. Not that it's not allowed, but
it's a dodgy design decision, and you'd better be sure that a value
type was the correct choice.

Of course reference types can be immutable as well. Object "constants"
are a good example.

The bottom line is that the most common use for structs involves
creating an immutable value type that acts like a fundamental type like
int, double, etc. Yes, there are other applications for value
semantics, but I see that as wandering more into expert territory.

Certainly one shouldn't use structs in C# in order to reproduce the
behaviour of C-style data-only structures, and then start passing the
structs by "ref" everywhere, which is what I tried (and my colleagues
here tried, and it looks like Dan tried...).
 
J

Jon Skeet [C# MVP]

Bruce Wood said:
True. I'm sorry if my post implied that value types _have_ to be
immutable. However, you must admit that if you have a mutable value
type then you're skating on thin ice. Not that it's not allowed, but
it's a dodgy design decision, and you'd better be sure that a value
type was the correct choice.

Of course reference types can be immutable as well. Object "constants"
are a good example.

The bottom line is that the most common use for structs involves
creating an immutable value type that acts like a fundamental type like
int, double, etc. Yes, there are other applications for value
semantics, but I see that as wandering more into expert territory.

Certainly one shouldn't use structs in C# in order to reproduce the
behaviour of C-style data-only structures, and then start passing the
structs by "ref" everywhere, which is what I tried (and my colleagues
here tried, and it looks like Dan tried...).

Yup, I'd go along with all of that.
 

Ask a Question

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

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

Ask a Question

Top