You cannot pass a reference type "by value". Let's review "by val"/
"by ref".
By default when you pass a variable reference into a method, it depends
on if that variable type is a reference type or a value type. Most
types, like SqlCommand, are a reference type. All the basic types like
int, bool, long, are value types.
Value types are stored on the "stack". When they are passed into a
method, that method gets it's own copy of that varible value. So that
value is now on the stack twice. So any changes to the copy is not
reflected in the calling method.
reference types are stored in the "heap". A pointer to that object
instance is passed into a method. That method gets it's own pointer to
that same object instance. Since that method has a pointer to the
orginal object, any changes to that object are affecting the "original"
object. There is NO way to get around this. What the calling method
cannot do is reassign that instance to a new instance of that type.
Well it can, but then it now points to that new instance, and any
changes to it does not affect the original.
There are two operators you can apply to a method parameter "out" and
"ref". When you apply either of these to a reference type the calling
method can reassign the object to a new instance. Then the keyword
causes that reassignment to affect the orginal calling methods pointer
to the object to now also point at the new instance.
So, in short, you can prevent a called method from reassigning a
varible to a new instance, but you cannot prevent it from modifying the
instance that you pass in.
But what you can do is pass in a copy of the original object. You can
do that for any type that supports "ICloneable" via the Clone() method.
The SqlCommand class does implement ICloneable, however, it has
"hidden" the method. You would have to cast your command to ICloneable
to do the clone. I've never tested this, so I'm not sure if it would
work.
Code:
SqlCommand myCommand = new SqlCommand(...)
ICloneable myCloneableComand = (ICloneable)myCommand;
SomeClass obj = new SomeClass()
obj.SomeMethod(myCloneableComand.Clone());
// anything SomeMethod did is not reflected in 'myCommand'.
Beware, however, as I believe this is just a shallow copy. Meaning
that any properties that are a reference type will represent the same
object in both SqlCommand instances. For instance, the Connection
property is a SqlConnection. So any change made to the connection of
the command passed into that "SomeMethod" will affect the original
'myCommand" instance as well.
I question what you would want to do in "obj.SomeMethod"? If it just
needs to react to a given property of the command, just pass in that
property value only. Can you give an example of what you are trying to
accomplish.