I've read the difference between passng and not passing ref in parameters, however, when would I want to use them?
For example, I had some logic in a method which could be refactored into its own method. Resharper 4.5 made one of the parameters a ref type but I didn't think I would have of done this if I did the refactoring manually.
Obviously I am missing some understanding. Perhaps an example of what happens when certain types or certain scenarios in coding miss the ref keyword will help?
Thanks
When used in a method's parameter list, the ref keyword indicates that an argument is passed by reference, not by value. The ref keyword makes the formal parameter an alias for the argument, which must be a variable. In other words, any operation on the parameter is made on the argument.
The ref keyword in C# is used for passing or returning references of values to or from Methods. Basically, it means that any change made to a value that is passed by reference will reflect this change since you are modifying the value at the address and not just the value.
In C#, arguments can be passed to parameters either by value or by reference. Remember that C# types can be either reference types ( class ) or value types ( struct ): Pass by value means passing a copy of the variable to the method. Pass by reference means passing access to the variable to the method.
ref keyword is used to pass data in bi-directional way. out keyword is used to get data in uni-directional way. Before passing a variable as ref, it is required to be initialized otherwise compiler will throw error.
Let me break that down into two questions:
1) When should one use ref/out formal parameter declarations when writing a method?
Use ref/out when you desire your method to be able to read and write a variable passed in from the caller, rather than merely reading a value.
2) Why does an "extract method" refactoring produce a ref parameter?
I don't know the details of Resharper, but I can make a guess. Consider the following evil mutable value type:
struct S
{
private int x;
public int X() { return this.x; }
public void M() { this.x += 1; }
}
You have a method:
void Foo()
{
S s = new S();
Fred(s);
Blah(s);
Bar(s);
s.M();
Console.WriteLine(s.X()); // prints 1
}
and you do "extract method" on the middle bit:
void NewMethod(ref S s)
{
Blah(s);
Bar(s);
s.M();
}
void Foo()
{
S s = new S();
Fred(s);
NewMethod(ref s);
Console.WriteLine(s.X()); // still prints 1
}
If instead you made a method without "ref" then calling NewMethod(s) would pass a copy of s to NewMethod. Remember, value types are copied by value; that's why we called them "value types". It would be the copy that gets mutated, and then s.X() returns zero. It is a bad idea for a refactoring to introduce a semantic change in a program, and it is difficult for a refactoring engine to know whether a given method relies on the mutability of a value type or not.
This is just another reason why you should avoid mutable value types.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With