HomeSearch

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 you 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. Before you can pass a ref parameter, you must assign it to a value. This is for the purpose of definite assignment analysis.

However: You don't need to assign an out parameter before passing it to a method. The compiler allows this.

Out: The out parameter in that method must assign the parameter before returning. This is required.

This program defines the Program class with Main and two other methods—SetString1 and SetString2. The methods have formal parameter lists with the reference parameter keywords.

SetString1: This has the ref keyword. Whenever you 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 you want to call SetString2, you must use the out keyword on its argument.

Tip: You do not need to assign the string parameter before sending it to SetString2.

Out
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
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.
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
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.Overloads
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.ParseTryGetValueTester-Doer
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
A summary. These keywords allow you to pass variable references, as opposed to object references. The actual storage location of the variable itself is copied on the method invocations.
© 2007-2019 Sam Allen. Every person is special and unique. Send bug reports to info@dotnetperls.com.
Home
Dot Net Perls