G
Guest
In C++, it is not uncommon to design a class to hold a pointer to another
object. For example:
class foo
{
Object * Obj;
void SetObj(Object * obj) { Obj = obj; }
Object * GetObj() { return Obj; }
};
The nice thing about this simple class is that once the pointer is set with
SetObj, it does not matter how, when, or where Obj is modified. Class foo
will be able to see the most recent updates to the object because it is not
using a copy, but rather a reference to the actual object that is being used
by other classes.
Under the .NET framework, classes or reference types also work the same way.
For example:
class foo
{
Object Obj;
void SetObj(Object obj) { Obj = obj; }
Object GetObj() { return Obj; }
}
This C# code is very similar to the C++ code above and works the same way as
the C++ code. However, consider the following code:
class foo
{
int Num;
void SetNum(int num) { Num = num; }
int GetObj() { return Num; }
}
The above code works quite a bit differently than the prior 2 examples. Num
is a native value type that is passed by value. So, a copy of the contents
of num is assigned to the class variable Num. If the integer passed to
SetNum is modified by another class outside of foo, then foo won't know about
it. Even if num were passed by reference, I don't believe there is any
legitimate safe mode C# syntax that will assign the pointer to the class
variable Num. So, it seems that reference types and value types have been
designed to operate quite differently in .NET. Why is that? I understand
that Java and other modern languages don't seem to have this problem.
As a developer, this is quite inconvenient. I am currently working on a C#
project where I have had to create classes like RefInt, RefDbl, and RefString
to simply hold the appropriate value type (with no other functionality) so
that my classes can be used without having to pass the value types each time
a method from my class is called. For example, here is some current code
from one of my projects:
public class RefInt
{
// This class exists as a work around to the fact that the .NET framework
does not allow
// native data types to be used as true objects, or for the address of a
native data type to
// be assigned like a regular reference type.
public int I; // The value to be used.
public override string ToString()
{
return I.ToString();
}
}
I am faced with the unhappy prospect of telling the users of my classes to
either always use the RefInt class variable directly in their code, or to
keep track of when they update their local variables that are being used with
my class and to move it into the RefInt variable before calling any of my
class methods.
The class that I'm writing encapsulates the functionality of a report file
with columns. The user of my class calls an add method to add columns. The
column data can be used with an int, double, or string and the add method
assigns the variable to be used to the class. So, the only options I see are
to either have the user always use one of my Ref wrapper classes (like
RefInt) in all their calculations, or tell them to move the local variable
into my wrapper class before calling my class methods. If anyone can suggest
some other way of doing it, I would love to hear it. But for right now,
these are the only 2 solutions that I see. Also, even if someone does think
of a better way to do this, the point about value types acting differently
than reference types is still of concern.
So, it seems to me that anytime the language forces you to do something
unpleasant like this, its bad for all concerned. Bad for my customers, bad
for me, and eventually its bad for Microsoft since other languages like Java
don't have this limitation. So, I am requesting Microsoft to remove this
limitation and make C# as well as all the other .NET languages truly object
oriented by making value types act like references.
How to do this with minimal impact? One way might be expand the native data
types such that for each value type a new reference-value type is added. The
reference-value type would have the same properties as a value type, except
that it would act as a reference and be allocated on the heap and subject to
garbage collection like other reference types. Value types would still work
the same way in this scenario. A way of assigning the address of a
reference-value type would have to be provided. The = operator should still
assign the contents of one variable to another in order to provide backward
compatibility. Perhaps := could be used to assign an address. Value types
could not have their address assigned and a reference-value could not be
assigned to anything other than another referernce-value variable of the same
type. This approach should be backwards compatible with all existing code.
Another simpler approach would be to simply create all variables on the heap
and thus subject them to garbage collection. If this were done, then there
would not be a need for a new set of reference-value variables. But, most
programs would run a little slower and the := assignment statement would
still be needed to assign the address.
I tried to submit this as a suggestion in the Microsoft MSDN product
feedback, but the system would not let me get past the search for
suggestions. So I a submitting this here. Could someone from Microsoft
please refer this suggestion to the appropriate team.
Thanks,
Bob Bryan
object. For example:
class foo
{
Object * Obj;
void SetObj(Object * obj) { Obj = obj; }
Object * GetObj() { return Obj; }
};
The nice thing about this simple class is that once the pointer is set with
SetObj, it does not matter how, when, or where Obj is modified. Class foo
will be able to see the most recent updates to the object because it is not
using a copy, but rather a reference to the actual object that is being used
by other classes.
Under the .NET framework, classes or reference types also work the same way.
For example:
class foo
{
Object Obj;
void SetObj(Object obj) { Obj = obj; }
Object GetObj() { return Obj; }
}
This C# code is very similar to the C++ code above and works the same way as
the C++ code. However, consider the following code:
class foo
{
int Num;
void SetNum(int num) { Num = num; }
int GetObj() { return Num; }
}
The above code works quite a bit differently than the prior 2 examples. Num
is a native value type that is passed by value. So, a copy of the contents
of num is assigned to the class variable Num. If the integer passed to
SetNum is modified by another class outside of foo, then foo won't know about
it. Even if num were passed by reference, I don't believe there is any
legitimate safe mode C# syntax that will assign the pointer to the class
variable Num. So, it seems that reference types and value types have been
designed to operate quite differently in .NET. Why is that? I understand
that Java and other modern languages don't seem to have this problem.
As a developer, this is quite inconvenient. I am currently working on a C#
project where I have had to create classes like RefInt, RefDbl, and RefString
to simply hold the appropriate value type (with no other functionality) so
that my classes can be used without having to pass the value types each time
a method from my class is called. For example, here is some current code
from one of my projects:
public class RefInt
{
// This class exists as a work around to the fact that the .NET framework
does not allow
// native data types to be used as true objects, or for the address of a
native data type to
// be assigned like a regular reference type.
public int I; // The value to be used.
public override string ToString()
{
return I.ToString();
}
}
I am faced with the unhappy prospect of telling the users of my classes to
either always use the RefInt class variable directly in their code, or to
keep track of when they update their local variables that are being used with
my class and to move it into the RefInt variable before calling any of my
class methods.
The class that I'm writing encapsulates the functionality of a report file
with columns. The user of my class calls an add method to add columns. The
column data can be used with an int, double, or string and the add method
assigns the variable to be used to the class. So, the only options I see are
to either have the user always use one of my Ref wrapper classes (like
RefInt) in all their calculations, or tell them to move the local variable
into my wrapper class before calling my class methods. If anyone can suggest
some other way of doing it, I would love to hear it. But for right now,
these are the only 2 solutions that I see. Also, even if someone does think
of a better way to do this, the point about value types acting differently
than reference types is still of concern.
So, it seems to me that anytime the language forces you to do something
unpleasant like this, its bad for all concerned. Bad for my customers, bad
for me, and eventually its bad for Microsoft since other languages like Java
don't have this limitation. So, I am requesting Microsoft to remove this
limitation and make C# as well as all the other .NET languages truly object
oriented by making value types act like references.
How to do this with minimal impact? One way might be expand the native data
types such that for each value type a new reference-value type is added. The
reference-value type would have the same properties as a value type, except
that it would act as a reference and be allocated on the heap and subject to
garbage collection like other reference types. Value types would still work
the same way in this scenario. A way of assigning the address of a
reference-value type would have to be provided. The = operator should still
assign the contents of one variable to another in order to provide backward
compatibility. Perhaps := could be used to assign an address. Value types
could not have their address assigned and a reference-value could not be
assigned to anything other than another referernce-value variable of the same
type. This approach should be backwards compatible with all existing code.
Another simpler approach would be to simply create all variables on the heap
and thus subject them to garbage collection. If this were done, then there
would not be a need for a new set of reference-value variables. But, most
programs would run a little slower and the := assignment statement would
still be needed to assign the address.
I tried to submit this as a suggestion in the Microsoft MSDN product
feedback, but the system would not let me get past the search for
suggestions. So I a submitting this here. Could someone from Microsoft
please refer this suggestion to the appropriate team.
Thanks,
Bob Bryan