Re: Abstract class variables question



"Peter Duniho" <NpOeStPeAdM@xxxxxxxxxxxxxxxx> wrote in message
news:2007111600330350073-NpOeStPeAdM@xxxxxxxxxxxxxxxxxx
On 2007-11-15 21:46:48 -0800, "tshad" <tfs@xxxxxxxxxxxxxx> said:

I always looked at a property as a conduit to some value but that it
didn't
do anything until you called it (get). So it was confusing that the
value
seemed to be "something" before being called by the debugger. But in
actuality, I guess you could say the debugger was doing a "get" to get
the
value.

Not only could I say that, I would. :)

That's how properties work. You have to call the getter method to get the
value. Since calling a getter is an instaneous event, rather than
something that's stored somewhere, a property's value is only known at the
time you call the getter.

Some properties never change in value, such as the one we're talking about
here. Others are more conventional, and change in value only when you
call the setter. And still others are changing in value all the time (at
this extreme, see for example DateTime.Now).

The one thing that all properties have in common is that whatever one
might consider the "value" of a property, the only way to know for sure
what the value is at any given moment is to call the getter for the
property. And the instance you call that getter, there are no fundamental
guarantees about what might be returned the next time you call the getter
(though many classes of course provide a guarantee above and beyond what
the language offers).

To me, it's sort of like a little Heisenberg thing going on. You have to
measure the state of the property to know its value. Granted, for most
properties measuring the state doesn't itself necessarily change the
state, but it could and more importantly you still can't say anything
about the future state of the property even having obtained the state at
some instantaneous point in time. :)


I'm not really sure what you mean. An object reference (given the .NET
terminology, I prefer to use the word "reference" over "pointer" in this
situation) points (or rather, refers) to the data structure. It
wouldn't
"point" to a specific property.

What I was saying was that when you do the line "_objCurrent = value;",
value can be anything (bool, int, string, etc). To the class it is just
an
object (not a bool, int or string). The statement doesn't care, which is
why you need to do the ValidateType before. The value really gets put on
the heap and _objCurrent is just a pointer to that location. Right?

Basically, yes.

I only sort of understand boxing.

If I understand it correctly, _objCurrent is just a pointer on the Stack
that points to something on the Heap.

Not really. _objCurrent is a field inside a class. All classes are
reference types, which means that all classes are allocated from the heap.
So _objCurrent is a memory location in the heap, that references something
else that's stored in the heap.

I understand that it is a field. But I thought that since the _objCurrent
is an object type that it is just a pointer but not actually an object until
it is assigned to something so it is null.

As far as boxing and the heap go, I assumed it was a pointer to the heap
from articles such as this:

http://www.c-sharpcorner.com/UploadFile/rmcochran/csharp_boxing02122006144943PM/csharp_boxing.aspx?ArticleID=967b4ba5-e4f6-4b80-8e6e-0f4cc23f8e6c

I may not have understood it completely.

When I assign true to an object, it does
1) a "memalloc" (from the C++ days) and grabs a portion of memory
2) puts the value (true in this case, "This is a test" in the case of a
string) there
3) then puts the pointer (reference) in _objCurrent.

That much is basically correct, not counting the hand-waving. :) There
is more to boxing though than just allocating a large enough area to hold
the value itself. It's oversimplifying things to say that just the value
is stored (that is, a boxed int for example is going to take more space
than just the 32 bits for the int).

Really?

Does it have more information about the actual object, such as what type of
object it is?

Well, all that _objCurrent "knows" is that it has a reference to
something
that is an Object. It doesn't even know that the object has a value
type
boxed inside it, never mind what the actual value of that value type is.

What is confusing is that Data is type "object", as you said. How does
it
know how much memory to allocate?

Because a reference is always just 32 bits. The act of boxing a value
type needs to know how much space to allocate, to contain the value type
along with the class that's containing it. But once the value type has
been boxed (and this occurs _before_ the assignment to the Data property),
it's just a regular reference and always only takes as much space to store
as any reference: 32 bits.


That is what is confusing about boxing.

According to the article above, unless I missed something, boxing actually
moves the data and you are looking at a different piece of data.

For example:

string A = "something"
string B;
B = A

Both A and B are referencing the same location. Such that if I say 'A =
"Something else";', A and B will both be equal to "Something Else".

But if you do
string A = "something";
object B;
B = A;
A = "Something Else"

A and B point to different locations whereas A will be "Something Else" and
B will be "something". Both A and B are pointers in both examples.

Maybe it is different with ints and strings.

(Ignoring the possibility of a 64-bit .NET for the moment :) )

I assume that the Property knows how much
data is being passed. Obviously, a string would/could take many bytes.
We
do the _ValidateType to check the type, but then we just move the value
(which could be any type) to the heap.

Well, a string is even easier, since the String class is already a
reference type. No boxing has to happen; the reference that is already a
reference to the string instance is simply copied to the _objCurrent field
that is the backing store for the Data property.

But again, the property does know how much data is being passed, because
that data is always 32 bits.

[...]
Actually, I do have a Nullhandling class that does just like my last
class
that we are working on and I plan on using the same techniques we did
here
to make it work. I use it for moving data to and from my database
records
and I use these classes to handle the nulls and track changes.

The call to move data from a database to my classes would be something
like:

NullHandler.GetValueFromDbObject((object)user["UserID"],ref userID);

where userID is defined as:

private IntType userID = new IntType();

Well, the first thing I notice is that you're using the "ref" keyword
inappropriately. The "userID" variable is already a reference type. So
the parameter is passing a reference. The reference is passed by value,
but it's still a reference and so even without the "ref" any changes you
make to the object in the called method will be reflected when accessing
the instance through "userID".

That may be the case.

I wrote this a few years ago and it does work. It seems that it didn't work
without the ref keyword. But they have been that I started building this
with a scalar that was not a reference type and I just kept the code the
same.


See Jon Skeet's most excellent article on the topic:
http://www.yoda.arachsys.com/csharp/parameters.html

Since a lot of the data is the same I was looking at whether to do the
same
type of thing. I'm not sure if it is worth it or not as it does work as
it
is but I may do it just for the practice.

Well, at the very least it does seem like you could consolidate all of the
"check for null, convert to type" code somehow. It sure seems like all of
those GetValueFromDbObject() overloads could be coalesced into a single
method that handles the checking for null.

That was what I was thinking about doing.

The way you've written that code, it appears that the caller makes the
determination of type before making the call. So one approach would be to
add a conversion method into your type classes (similar to the
_TypeRequired property, it would be abstract and then implemented by each
concrete type), instantiate the necessary class before calling
GetValueFromDbObject(), and then in that method call the conversion method
to convert from the database object to the necessary C# type for storage.


Before I was thinking about rewritting the NullHandler up until last night.
And it was more necessary since, if you remember, the old DataType Classes
had variables that were the type of the class (BoolType class had First as a
boolean, IntType class had First as an int). Now the variables in the class
are objects. So maybe I can now consolidate them into the DataType class.

The whole point of the NullHandler class is to handle data going to and from
a database where the values can be null in the database and not in my c#
code.

When calling to 2 types of calls in my NullHandler:

NullHandler.GetValueFromDbObject((object)user["UserID"],ref userID);

and in my Property where I use both get the data from the DB and Set the
Data to back to the DB

public object DivisionID
{
get
{
object value = null;
return NullHandler.SetDbObjectValueFromValue(divisionID,ref value);
}
set
{
NullHandler.GetValueFromDbObject(value,ref divisionID);
}
}

The code in the NullHandler for my SetDBObjectValueFromValue would look
something like:

public static object SetDbObjectValueFromValue(LongType sourceValue, ref
object dbObjectValue)
{
if(sourceValue.IsNull())
dbObjectValue = DBNull.Value;
else
dbObjectValue = sourceValue.Data;
return dbObjectValue;
}

Most of this was based on the objects fields being of a specific type and in
the new style they are all objects.

I don't know enough about the overall design to know that's the best way
to handle it, but given the code you've posted so far, it's certainly one
way and would at least be better than having all those overloads. :)

Sounds good to me.

Thanks,

Tom


.



Relevant Pages

  • Re: String Reference Type
    ... Therefore its always allocated in the heap and a variable of string type ... Dim y As String ... As with all classes in this case y and x both reference the same String ...
    (microsoft.public.dotnet.framework.aspnet)
  • Re: Complex Specified Information - Pitman Formula
    ... Therefore a significant match between a reference and a test ... string is good evidence of non-random production. ... and there are no finite algorithms to compute their digits. ... probabilities of the different symbols the information source can produce. ...
    (talk.origins)
  • Re: Function Declaration
    ... >> | Public Function CleanSomething(ByVal value As String) As String ... >> refer to how parameters are passed, while Reference Type & Value Type ... >> ByRef passes a reference to the variable as the parameter. ... >> actual object on the heap. ...
    (microsoft.public.dotnet.languages.vb)
  • Re: String Reference Type
    ... All unary and binary operators have predefined implementations that are ... Therefore its always allocated in the heap and a variable of string ... As with all classes in this case y and x both reference the same String ... language depandant matter as below. ...
    (microsoft.public.dotnet.framework.aspnet)
  • Re: Boxing and Unboxing ??
    ... They are on the heap to avoid lifetime issues. ... int *retrieve ... instead of passed by reference. ... overhead, merely boxing initialization. ...
    (microsoft.public.dotnet.languages.csharp)