473,320 Members | 1,930 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Value/Reference Types - Oooooops!

Hi,
I'm new to C# and have run into a problem of my own making! I
originally took from the documentation that as long as I didn't use
the "ref" keyword in method declarations, that everything would be
passed "by value". I now believe I was incorrect and that it's only
types like int, bool, etc. that behave like that? i.e. things like
XmlDocument are always passed by reference in method calls?

I was writing a "wrapper" class around a PRIVATE XmlDocument but
because of the above lack of understanding, I don't think it's as
"encapsulated" as I thought it was!

e.g. in "MyWrapper" class:

-------------------------------------------------
....
private XmlDocument mvar_TheDocument = new XmlDocument(); //note
"private"
....
public MyWrapper()
{
mvar_TheDocument.Load("some path");
}

public XmlNode GetNodeByID(string sID)
{
return mvar_TheDocument.SelectSingleNode("/blah blah find the
node");
}
....
-------------------------------------------------
So, on some WebForm I now say:

....
MyClass objMyClass = new MyClass();
XmlNode objNode = objMyClass.GetNodeByID(sSomeID);
....
objNode.InnerXml = string.empty;
....

!!! Guess what? :-) The node in "mvar_TheDocument" gets cleared! Not
what I had in mind - I want MyClass to be the only place with code
that can update that XmlDocument.
The problem is worse because MyClass persists for a long time, over
many calls - so it's likely that I'm going to make a "coding mistake"
at some point and inadvertantly modify my core document.

What's the best thing to do (apart from sending me on a training
course!)? I assume I have to return a "copy" of the node somehow? How
does this impact memory management - does it get cleaned up once
nothing needs the "copy" any more or do I have to set "objCopy = null"
everywhere now?

Obviously, I've also misunderstood the "private" member concept - even
though the XmlDocument is "private", there's no runtime error when
"external" code indirectly modifies it like that? Wow! I'm way off
with this stuff!

Thanks for any help!
Nov 12 '05 #1
5 2928
When you pass (by value) a reference to an object, the called method gets
exactly that: a copy of the reference to the object. Since it was passed by
value, the called method can't modify the original reference (the one in the
calling method's scope), but it can change the state of the object that the
argument refers to, providing the object has any public members that can
change its state.

If, on the other hand, you pass a reference BY REFERENCE, the called method
is looking directly at the calling method's variable, and could change it.
So when the method returns, the calling method might find that the variable
now points to a different object.

Clear as mud?
Tom Dacon
Dacon Software Consulting

"Jerry Morton" <Je************@mail.com> wrote in message
news:11**************************@posting.google.c om...
Hi,
I'm new to C# and have run into a problem of my own making! I
originally took from the documentation that as long as I didn't use
the "ref" keyword in method declarations, that everything would be
passed "by value". I now believe I was incorrect and that it's only
types like int, bool, etc. that behave like that? i.e. things like
XmlDocument are always passed by reference in method calls?

I was writing a "wrapper" class around a PRIVATE XmlDocument but
because of the above lack of understanding, I don't think it's as
"encapsulated" as I thought it was!

e.g. in "MyWrapper" class:

-------------------------------------------------
...
private XmlDocument mvar_TheDocument = new XmlDocument(); //note
"private"
...
public MyWrapper()
{
mvar_TheDocument.Load("some path");
}

public XmlNode GetNodeByID(string sID)
{
return mvar_TheDocument.SelectSingleNode("/blah blah find the
node");
}
...
-------------------------------------------------
So, on some WebForm I now say:

...
MyClass objMyClass = new MyClass();
XmlNode objNode = objMyClass.GetNodeByID(sSomeID);
...
objNode.InnerXml = string.empty;
...

!!! Guess what? :-) The node in "mvar_TheDocument" gets cleared! Not
what I had in mind - I want MyClass to be the only place with code
that can update that XmlDocument.
The problem is worse because MyClass persists for a long time, over
many calls - so it's likely that I'm going to make a "coding mistake"
at some point and inadvertantly modify my core document.

What's the best thing to do (apart from sending me on a training
course!)? I assume I have to return a "copy" of the node somehow? How
does this impact memory management - does it get cleaned up once
nothing needs the "copy" any more or do I have to set "objCopy = null"
everywhere now?

Obviously, I've also misunderstood the "private" member concept - even
though the XmlDocument is "private", there's no runtime error when
"external" code indirectly modifies it like that? Wow! I'm way off
with this stuff!

Thanks for any help!

Nov 12 '05 #2
Tom - I read your reply (twice :-) and I do now understand. It's
certainly an interesting nuance.

I found that if I return a "copy" of my data I can avoid the problem,
however I still have a problem with "XmlNode":

e.g.

-------------------------------------------------
....
private XmlDocument mvar_TheDocument = new XmlDocument(); //note
"private"
....
public MyWrapper()
{
mvar_TheDocument.Load("some path");
}
public XmlDocument GetDocument()
{
//The following returns a "copy" of the document - the "private
mvar_TheDocument" remains untouchable outside this object.
XmlDocument objNewDoc = new XmlDocument();
objNewDoc.LoadXml(mvar_TheDocument.OuterXml);
return objNewDoc;
}

public XmlNode GetNodeByID(string sID)
{
//How do I return a "copy" of an XmlNode - The following line gets a
compiler error: "Cannot create an instance of the abstract class or
interface 'System.Xml.XmlNode'"
XmlNode objNewNode = new XmlNode();
...
}
....
-------------------------------------------------

How do I do this for "XmlNode". Is this "copy" method even the right
way to do all this?

Although I understand HOW it happens, I'm still not clear WHY .NET
allows a "private" member variable to be accessed this way. Seems
inconsistent?

Thanks.

"Tom Dacon" <td****@community.nospam> wrote in message news:<#X**************@TK2MSFTNGP12.phx.gbl>...
When you pass (by value) a reference to an object, the called method gets
exactly that: a copy of the reference to the object. Since it was passed by
value, the called method can't modify the original reference (the one in the
calling method's scope), but it can change the state of the object that the
argument refers to, providing the object has any public members that can
change its state.

If, on the other hand, you pass a reference BY REFERENCE, the called method
is looking directly at the calling method's variable, and could change it.
So when the method returns, the calling method might find that the variable
now points to a different object.

Clear as mud?
Tom Dacon
Dacon Software Consulting

Nov 12 '05 #3


Jerry Morton wrote:

public XmlNode GetNodeByID(string sID)
{
//How do I return a "copy" of an XmlNode - The following line gets a
compiler error: "Cannot create an instance of the abstract class or
interface 'System.Xml.XmlNode'"
XmlNode objNewNode = new XmlNode();


You can clone nodes in the DOM e.g.
node.CloneNode(true)
to create a clone. However that cloned node still belongs to the same
ownerDocument as node so I can currently not assess whether that is of
any help to you.
Maybe you can explain in more detail how you want to consume the node
returned by that method.

--

Martin Honnen
http://JavaScript.FAQTs.com/
Nov 12 '05 #4
Hi Martin,
I would prefer that the node returned from my function had no
relationship to the private XmlDocument. Can XmlNodes even exist in
isolation like this? i.e. without a parent XmlDocument? I appreciate
that a CLONED node may not cause the same problems (like setting
objNode.InnerXml=string.empty!) however this "cloning" does sound like
a "memory leak waiting to happen"? This object persists for a long
time too...

The purpose of all this is to completely encapsulate a PRIVATE
XmlDocument so that it can't be modified by code outside the class. I
can't be the first person who want to do this :-)

I still can't believe that a private member variable behaves this way.
However, if it does then I can live with making "copies" of the
document to pass back from functions. But does this mean that when I
only want to pass one node of the document, I actually have to pass
back an XmlDocument containing only that node?

Martin Honnen <ma*******@yahoo.de> wrote in message news:<eO**************@TK2MSFTNGP10.phx.gbl>...
Jerry Morton wrote:

public XmlNode GetNodeByID(string sID)
{
//How do I return a "copy" of an XmlNode - The following line gets a
compiler error: "Cannot create an instance of the abstract class or
interface 'System.Xml.XmlNode'"
XmlNode objNewNode = new XmlNode();


You can clone nodes in the DOM e.g.
node.CloneNode(true)
to create a clone. However that cloned node still belongs to the same
ownerDocument as node so I can currently not assess whether that is of
any help to you.
Maybe you can explain in more detail how you want to consume the node
returned by that method.

Nov 12 '05 #5


Jerry Morton wrote:

I would prefer that the node returned from my function had no
relationship to the private XmlDocument. Can XmlNodes even exist in
isolation like this? i.e. without a parent XmlDocument? I appreciate
that a CLONED node may not cause the same problems (like setting
objNode.InnerXml=string.empty!) however this "cloning" does sound like
a "memory leak waiting to happen"? This object persists for a long
time too...
Inside the DOM object model implemented in .NET a node always belongs to
its owner document, modelled in the
node.OwnerDocument
property. Thus even if you clone nodes with
node.CloneNode()
you still have nodes associated with the owner document (and linked to
it via node.OwnerDocument).
As for the memory leak, managed code in .NET has garbage collection so
once variables referencing nodes go out of scope they are available for
garbage collection. I am not sure what else you could do (or even expect
to happen behind the scenes) than cloning nodes.
The purpose of all this is to completely encapsulate a PRIVATE
XmlDocument so that it can't be modified by code outside the class. I
can't be the first person who want to do this :-)

I still can't believe that a private member variable behaves this way.
However, if it does then I can live with making "copies" of the
document to pass back from functions. But does this mean that when I
only want to pass one node of the document, I actually have to pass
back an XmlDocument containing only that node?


As said, you can use CloneNode to create a clone of your node but that
clone is still linked to the original document via the OwnerDocument
property. And of course while the original node might sit somewhere in
the document tree (have a ParentNode) the cloned node doesn't have a
ParentNode.

--

Martin Honnen
http://JavaScript.FAQTs.com/
Nov 12 '05 #6

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Javier Campos | last post by:
WARNING: This is an HTML post, for the sake of readability, if your client can see HTML posts, do it, it doesn't contain any script or virus :-) I can reformat a non-HTML post if you want me to (and...
1
by: Rafael Veronezi | last post by:
Just to fix, correct me if I am wrong... With reference types (objects), if I assign an object to another, the assignment will be the address of the object, and not a copy of it's contents right?...
19
by: daniel | last post by:
This is a pretty basic-level question, but I'd really like to know, so thanks for any help or pointers you can provide (like what I would google for ;o) Suppose: <code> myFunc() {
24
by: ALI-R | last post by:
Hi All, First of all I think this is gonna be one of those threads :-) since I have bunch of questions which make this very controversial:-0) Ok,Let's see: I was reading an article that When...
5
by: Zach | last post by:
When it is being said that, "value types are created on the stack or inline as part of an object". If a value type is created in an object, and that object is being called, the value type in that...
4
by: Jon Slaughter | last post by:
I'm reading a book on C# and it says there are 4 ways of passing types: 1. Pass value type by value 2. Pass value type by reference 3. Pass reference by value 4. Pass reference by reference. ...
11
by: garyusenet | last post by:
I have 'cli via c# on order', and in the mean time am reading 'Pro C# 2005 and the .NET platform' (Andrew Troelson). I'm just reading about the 'five types defined in the CTS'. Specifically Struct....
45
by: Zytan | last post by:
This returns the following error: "Cannot modify the return value of 'System.Collections.Generic.List<MyStruct>.this' because it is not a variable" and I have no idea why! Do lists return copies...
10
by: Robert Dailey | last post by:
Hi, I noticed in Python all function parameters seem to be passed by reference. This means that when I modify the value of a variable of a function, the value of the variable externally from the...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
0
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.