
Object behavior for simple data types?
Quote:
> So, can I say that value types (like String, Long, ...)
> are no 'real' objects? So I have to deal with them not
> like a normal object.
Value types *are* objects. An object is a value type or a reference type.
String is not a value type, it's a reference type.
What do you mean with "normal" objects?
The difference between a value type and a reference type is the way the
object is stored in memory.
A variable is a name for a block of memory. If you declare a Byte variable,
the size of the block of memory is 1 byte (surprise). If you take Integer,
it's 4 and it's 8 bytes for Long. And so on. If you define a structure, it's
the same: The block of memory contains all the variables declared within the
structure. If the structure contains two longs, the block of memory occupied
by a variable is 16 bytes in size. => the variable contains the object.
If the type of the variable is a reference type, the size of the block of
memory is always 4 bytes (at least under win32). This is true for String,
Form, Textbox and all other reference types. These 4 bytes (32-Bit-Interger
(or IntPtr)) contain the address of the object. If a variable contains the
value 1234567, the object is stored at the memory location 123467. If the
variable contains the value 0, it does not reference an object. We say that
the variable Is Nothing. => the variable contains a reference to the object.
As you can see, you can not store "Nothing" in a value type because we do
not need a reference to a value type. A byte can have a value between 0 and
255 but nothing else that can tell us that it is Nothing.
In addition, we have boxed value types:
Dim o as object
o = 17L 'Long (8 bytes)
o = new Form1()
What now? What is the size of "o"? o can contain a value type or a reference
type. A value type requires the variable to have the size that the value
type needs. It is 8 bytes for long, but 4 bytes (the reference) for a Form
object. So, how can both objects be stored in the same variable? This is
done by boxing: If you declare a variable "As Object", it's size is always 4
bytes and it contains a reference to the object (or no reference, i.e. it Is
Nothing). After assigning a Long value, o contains a reference to a block of
memory that contains the Long value. After assigning the Form object, it
contains a refernce to a block of memory containing all fields of a Form
object.
Boxing can be used for distinguishing between Nothing and a value type. You
can set o to Nothing or to one of the numeric values you mentioned in your
first posting. As I wrote, the disadvantage is the lack of type safety. This
means, you can store everything in o, not only Nothing or Long.
You can avoid this by writing a wrapper class:
class LongWrapper
public Value as Long
Public Sub New(byval VAlue as long)
me.value = value
end sub
end class
Now you can declare
dim wrappedlong as LongWrapper
and assign Nothing or, for example "New LongWrapper(17)"
Just a suggestions. There are (at least) two other solutions:
Write a property (type: object) that does a runtime-check if the passed
value is Nothing or Long. If not, throw an exception. Drawback: No compile
time check.
Second: Write a property (type: Long) and two additional methods:
SetPropertyNothing and IsPropertyNothing.
Both approaches have the same disadavantage: Within the class, you still can
set the field to any type. That's why a wrapper class can be useful.
Armin