xmldocument byval to a function is changing the input doc? Help

G

Guest

I have an example below that is not working correctly.
I have a web application that passes a System.Xml.XmlDocument object
"oInputDoc" around to functions byval.
I do not want the "oInputDoc" object to change when it is passed into
"myFunction".
I want to use the data in the object, modify it "myFunction" and then pass
it out as an "oOutputDoc".
On the way back out of the function, the "oInputDoc" is being changed by
..net, not sure why it is changing, as it is set to byval as it is passed into
"myFunction"

see example below,which is a scaled down version of what is happening to me.

private void Page_Load(object sender, System.EventArgs e)
{
// Put user code to initialize the page here
string s = "<root><name>Keep this Data here</name></root>";
XmlDocument oInputDoc = new XmlDocument();
XmlDocument oOutputDoc = new XmlDocument();
oInputDoc.LoadXml(s);
oOutputDoc = myFunction(oInputDoc);
Response.Write(oInputDoc.OuterXml);
Response.Write("<BR>");
Response.Write(oOutputDoc.OuterXml);
}
private XmlDocument myFunction(System.Xml.XmlDocument oInputDoc)
{
string s = "<root><name>New Output Data</name></root>";
oInputDoc.LoadXml(s);
return oInputDoc;
}

any help is greatly appreciated.

Thanks,
Bob
 
K

Kai Brinkmann [Microsoft]

Why would you think that your XML document is being passed by value? An
XmlDocument is *not* a value type and is thus passed by reference by
default. So your call

oOutputDoc = myFunction(oInputDoc);

passes a *reference* to oInputDoc into the method. So after the method
returns, oOutputDoc and oInputDoc will be identical. You need to make a
clone of oInputDoc inside the method and modify this new object if you want
to change this behavior.

--
Kai Brinkmann [Microsoft]

Please do not send e-mail directly to this alias. This alias is for
newsgroup purposes only.
This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jon Skeet [C# MVP]

Bob P said:
I have an example below that is not working correctly.
I have a web application that passes a System.Xml.XmlDocument object
"oInputDoc" around to functions byval.
I do not want the "oInputDoc" object to change when it is passed into
"myFunction".
I want to use the data in the object, modify it "myFunction" and then pass
it out as an "oOutputDoc".
On the way back out of the function, the "oInputDoc" is being changed by
.net, not sure why it is changing, as it is set to byval as it is passed into
"myFunction"

The *reference* is being passed by value, but the object itself can
change. It's very important to to understand the difference between
(and the similarities between) passing something *by* reference and
passing a reference by value.

See http://www.pobox.com/~skeet/csharp/parameters.html
 
J

Jon Skeet [C# MVP]

Kai Brinkmann said:
Why would you think that your XML document is being passed by value? An
XmlDocument is *not* a value type and is thus passed by reference by
default.

No it's not. The semantics *are* pass by value, but they're passing the
*reference* by value, which isn't the same thing as pass-by-reference
semantics. The actual XML document object itself isn't being passed at
all.

See http://www.pobox.com/~skeet/csharp/parameters.html
 
K

Kai Brinkmann [Microsoft]

Ok, Jon, you got me ;) Thanks for calling me on this!

I concede the point that there is definitely an important distiction between
passing references by value and passing by reference. Obviously, this makes
a big difference for value types, too. But in this particular example, both

oOutputDoc = myFunction(oInputDoc); // pass reference by value

and

oOutputDoc = myFunction(ref oInputDoc); // pass by reference

would essentially result in the same thing. Even using pass-by-value
semantics, you are only passing an object reference and the original
XmlDocument referenced by oInputDoc is modified.

I think this explains why many programmers (myself included, I admit) often
refer to objects as being "passed by reference", even though the objects
themselves are never actually passed at all. But you are quite right to
state that this statement is at best inaccurate.
--
Kai Brinkmann [Microsoft]

Please do not send e-mail directly to this alias. This alias is for
newsgroup purposes only.
This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jon Skeet [C# MVP]

Kai Brinkmann said:
Ok, Jon, you got me ;) Thanks for calling me on this!

I concede the point that there is definitely an important distiction between
passing references by value and passing by reference. Obviously, this makes
a big difference for value types, too. But in this particular example, both

oOutputDoc = myFunction(oInputDoc); // pass reference by value

and

oOutputDoc = myFunction(ref oInputDoc); // pass by reference

would essentially result in the same thing.

Only if myFunction doesn't change the value of its formal parameter, of
course.
Even using pass-by-value
semantics, you are only passing an object reference and the original
XmlDocument referenced by oInputDoc is modified.
Yes.

I think this explains why many programmers (myself included, I admit) often
refer to objects as being "passed by reference", even though the objects
themselves are never actually passed at all. But you are quite right to
state that this statement is at best inaccurate.

Yes - unfortunately I've seen several people who understand pass-by-
reference correctly, and have assumed that they could do:

void SwapDocuments (XmlDocument doc1, XmlDocument doc2)
{
XmlDocument temp = doc1;
doc1 = doc2;
doc2 = temp;
}

and achieve a swap. (You can do this with pass-by-reference, of
course.)

Getting this right is one of my pet peeves, I'm afraid :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top