<ja**********@g mail.com> wrote in message
news:11******** *************@p 79g2000cwp.goog legroups.com...
The Petar wrote: Prints out "0", instead of the naturally expected "88".
In other words, you want S to reference sematics instead of value
sematic. So, then, why are you make it a struct instead of a class?
I don't know, maybe to allocate an array of 1000 of them as local variables
without hammering the garbage collector. Maybe because 99% of the time the
type is used with value semantics, and calling Clone() all the time is just
too much (and again hammers the garbage collector). Maybe it's predefined
as a struct in someone else's class library. In short, a million reasons.
For example, how about having a Vector class:
class Vector
{
private Point internalHead;
public Point Head
{
get { return internalHead; }
set { internalHead = value; }
}
//same for tail
}
System.Drawing. Point is a struct. Microsoft already made that choice. But
now you can do (where v is type Vector):
int x = v.Head.X;
but not
v.Head.X = x*3; // changes temporary Point returned from get_Head()
In the good old days of C++, there was no difference between struct and
class. Reference and value semantics were both available for all
user-defined types using language features such as "references ".
MyStruct operator[](int index) const; // value semantics
MyStruct& operator[](int index); // reference semantics
Actually this has been true from ordinary C, but in C you had to use
pointers, which required the caller to use a different syntax, and
encouraged breaking type-safety. C# is a throwback to C...
The answer is: yes you can get reference semantics with structs. You must
use pointers to do so. You use the -> operator familiar to C/C++
programmers for accessing structure members through a pointer. And you must
mark your code as "unsafe"... though the documentation suggests unsafe is
only needed if you do pointer arithmetic. I haven't tested whether you can
do:
int a = 5;
int* p = &a;
p->ToString();
without an unsafe context. There's no pointer arithmetic, so type-safety is
assured.
However, you're going to have a problem when you need a pointer to a struct
inside a ref class, because the garbage collector can change the object.
What you really need is the fancy support Microsoft added to C++/CLI to
handle all of this very neatly: tracking references (%) and interior_ptr.
If C# let you override operator->, you could have interior_ptr in C# pretty
quick. Instead, you need to have member (so they can access the private
fields backing the public properties) classes or structs, with properties
defined so that they proxy the properties of the private field.
class Vector
{
private Point internalHead;
public class RefHeadPoint
{
private Point? fromPoint;
private Vector boss;
public RefHeadPoint(Po int pt) : fromPoint(pt), boss(null) {}
public RefHeadPoint(Ve ctor v) : fromPoint(null) , boss(v) {}
public static implicit operator Point(RefHeadPo int pt) { return
pt.pt ?? pt.boss.interna lHead; }
public static implicit operator RefHeadPoint(pt ) { return new
RefHeadPoint(pt ); }
public int X
{
get { return (pt ?? boss.internalHe ad).X; }
set { if (pt.HasValue) pt.X = value; else boss.internalHe ad.X =
value; }
}
// same for Y
}
public RefHeadPoint Head
{
get { return new RefHeadPoint(th is); }
set { internalHead = (Point)value; }
}
//same for tail
}
and now you can write:
v.Head.X = x*3;