Thursday, March 29, 2012

setting object reference to null in a function

ok, could someone explain this:

public static void SomeFunction()
{
SqlCommand cmd = new SqlCommand();
SomeOtherFunction(cmd);
Console.WriteLine(cmd.CommandText);
}
public static void SomeOtherFunction(SqlCommand cmd)
{
cmd.CommandText = "something";
cmd = null;
}

why is the command text being written out at the Console.WriteLine step even though the reference was set to null in the other function??By default, functions receive the value of the object passed to them, not the object itself. That means that someOtherFunction actually creates a copy of the cmd object then assigns the value Null to it; it doesn't change the original cmd object.

This default behaviour is ByVal; you need to specify ByRef to do what you want. I use VB rather than C#, but I guess the syntax you need is

public static void SomeOtherFunction(ByRef SqlCommand cmd)
so explain why SomeOtherFunction is able to change the value of cmd.CommandText??

the value output in Console.WriteLine *is* the changed value of cmd.CommandText.

so in other words, the function does modify the original object's parameters (that's expected with an object), but is not able to set it to null. that's what i am confused about :)
just to clarify:


public static void SomeFunction()

{
SqlCommand cmd = new SqlCommand();
SomeOtherFunction(cmd);
Console.WriteLine(cmd.CommandText); //<-- THE VALUE WRITTEN OUT IS "SOMETHING"
// surely it should be either an empty string (if the other function does not modify the object)
// or null if the other function does modify the object
}

public static void SomeOtherFunction(SqlCommand cmd)
{
cmd.CommandText = "something";
cmd = null;
}


I've changed the variable names to help show what is happening.
public static void SomeFunction()
{
String ORIGINAL_string = "Set initially";
Console.WriteLine(ORIGINAL_string); //<-- THE VALUE WRITTEN OUT IS "Set initially"
SomeOtherFunction(ORIGINAL_string);
Console.WriteLine(ORIGINAL_string); //<-- THE VALUE WRITTEN OUT IS "Set initially"
}

public static void SomeOtherFunction(String COPYOF_string)
{
COPYOF_string = "something else";
COPYOF_string = null;
Console.WriteLine(COPYOF_string); //<-- THE VALUE WRITTEN OUT IS "something else"
Console.WriteLine(ORIGINAL_string); //<-- Should return an error, since this ORIGINAL_string is not declared in this method
}

As staplefordbill said, by default variables are passed ByVal (which really means a COPY is passed). The alternative is ByRef, which is more like passing the ORIGINAL.

Does that help?
no.. your code is passing strings.. which are values types, so are passed byval. the behaviour is expected there as you stated.

my code is passing objects, which is passed by reference. the problem is, i can modify the reference.. but it just seems to ignore the null setting. why?
Hi,

Here the pointer to the command object is sent to the function as byval.
u set the pointer sent to function as null which never gets reflected in the main function,
but the the value set to the object persists in the main fuction because u
only set the pointer to null.

To get the expected results send the parameters as byref.
public static void SomeFunction()
{

SqlCommand cmd = new SqlCommand();

SomeOtherFunction(ref cmd);//here note the keyword ref

Console.WriteLine(cmd.CommandText); //here u will get an error as the object is set to null if u pass by ref.
}

public static void SomeOtherFunction(ref SqlCommand cmd)//here note the keyword ref
{
cmd.CommandText = "something";
cmd = null;
}

Good Day,
SArun
Variables of type String are objects, too. So the effect is the same ... unless you explicitly state that your method is to receive its parameter ByReference, it will default to ByValue.

This MSDN page talks aboutPassing Parameters in C#.

0 comments:

Post a Comment