C# ref Keyword

Use the ref keyword on arguments. A ref argument can be read and written to.

Ref. A ref parameter is passed as a reference, not a value. This means we can assign the parameter in the called method and have it also be assigned at the calling site.Parameters

Difference. There is a difference between ref and out. Unlike with "out," we do not need to assign an initial value to ref before passing it to a method.

Initial example. This program defines the Program class with Main and 2 other methods—SetString1 and SetString2. The methods have formal parameter lists with ref keywords.
SetString1: This uses the ref keyword. Whenever we pass a string to this method, it must have the ref keyword.
Then: When the method is called, the storage location of the string variable is copied to the method.
SetString2: This has the out keyword. Whenever we want to call SetString2, we must use the out keyword on its argument.
Tip: We do not need to assign the string parameter before sending it to SetString2.
C# program that uses ref and out using System; class Program { static void Main() { string value1 = "cat"; // Assign string value. SetString1(ref value1); // Pass as reference parameter. Console.WriteLine(value1); // Write result. string value2; // Unassigned string. SetString2(1, out value2); // Pass as out parameter. Console.WriteLine(value2); // Write result } static void SetString1(ref string value) { if (value == "cat") // Test parameter value. { Console.WriteLine("Is cat"); } value = "dog"; // Assign parameter to new value. } static void SetString2(int number, out string value) { if (number == 1) // Check int parameter. { value = "one"; // Assign out parameter. } else { value = "carrot"; // Assign out parameter. } } } Output Is cat dog one

Example 2. We can refactor code that acts upon multiple local variables or fields. We create a method with a ref argument. And then we pass each separate variable to this method.
Warning: Using a loop for this pattern may be clearer and faster. If your program happens to use separate fields, though, this can help.
Note: The ref argument in the NullIf method both reads and writes the string. It is an input and output argument.
C# program that uses ref argument using System; class Program { static void Main() { string v1 = "dot"; string v2 = "net"; string v3 = "perls"; NullIf(ref v1); NullIf(ref v2); NullIf(ref v3); Console.WriteLine(v1); Console.WriteLine(v2); Console.WriteLine(v3); } static void NullIf(ref string value) { if (value == "net") { value = null; } } } Output dot perls

Ref returns. A method can return a reference to an argument or a local. This is useful if we want to modify the returned object, and have these modifications reflected in the current scope.
Here: We pass 2 Test structs to the HigherValue method. It compares the structs, and returns a reference to one of them.
Main: We have 2 local variables and we pass references of these to HigherValue. We modify the returned struct.
Finally: The modification affects the local variables in the Main method. So the ref return affects the local state of Main.
C# program that uses ref returns using System; struct Test { public int Value; } class Program { static ref Test HigherValue(ref Test left, ref Test right) { // Compares the two Test struct arguments. // ... Return a reference to the one with the higher value. if (left.Value > right.Value) { return ref left; } else { return ref right; } } static void Main() { Test t1; t1.Value = 10; Test t2; t2.Value = 20; // Get the struct with the higher value. // ... Then modify its value. HigherValue(ref t1, ref t2).Value = 30; // Display values of 2 structs. Console.WriteLine(t1.Value); Console.WriteLine(t2.Value); } } Output 10 30

Ref returns, notes. To use a ref return to our advantage, a mutable struct (or array) is needed. We can assign to the result of a method—this effect is reflected in the current method.Array: return ref

Definite assignment. The compiler performs a form of static analysis called definite assignment analysis. The compiler proves that each variable is initialized to a value before it is used.

Implementation. The difference between ref and out is in the C# language itself. In the intermediate language, we find that the ref and out parameters are called with the "string&" type.
Note: The "string" type actually aliases the System.String type in the base class library, so it is not special-cased here.

FxCop. The FxCop tool will warn you when you use ref and out parameters. It is considered that the best object-oriented design methodologies will return new objects.

A warning. Ref and out can confuse the overload resolution step in the C# compiler. For this reason, it is a bad idea to mix ref and out parameters in an interface or object method group.Overload

Uses. Out is sometimes used in methods that enhance performance—it can lead to simpler code. But often it makes code more complex and should be avoided.int.ParseTryGetValue

A summary. The ref keyword allows us to pass variable references, as opposed to object references. The storage location of the variable itself is copied on the method invocations.

© 2007-2020 Sam Allen. Send bug reports to info@dotnetperls.com.