ref return and ref local C# with Example



ref return and ref local C# with Example

Ref returns and ref locals are useful for manipulating and returning references to blocks of memory instead of 
copying memory without resorting to unsafe pointers. 
Ref Return 
public static ref TValue Choose( 
Func condition, ref TValue left, ref TValue right) 
{ 
return condition() ? ref left : ref right; 
} 
With this you can pass two values by reference with one of them being returned based on some condition: 
Matrix3D left = …, right = …; 
Choose(chooser, ref left, ref right).M20 = 1.0; 
Ref Local 
public static ref int Max(ref int first, ref int second, ref int third) 
{ 
ref int max = first > second ? ref first : ref second; 
return max > third ? ref max : ref third; 
} 
… 
int a = 1, b = 2, c = 3; 
Max(ref a, ref b, ref c) = 4; 
Debug.Assert(a == 1); // true 
Debug.Assert(b == 2); // true 
Debug.Assert(c == 4); // true 
Unsafe Ref Operations 
In System.Runtime.CompilerServices.Unsafe a set of unsafe operations have been defined that allow you to 
manipulate ref values as if they were pointers, basically. 
For example, reinterpreting a memory address (ref) as a different type: 
byte[] b = new byte[4] { 0x42, 0x42, 0x42, 0x42 }; 
ref int r = ref Unsafe.As(ref b[0]); 
Assert.Equal(0x42424242, r); 
0x0EF00EF0; 
Assert.Equal(0xFE, b[0] | b[1] | b[2] | b[3]); 
Beware of endianness when doing this, though, e.g. check BitConverter.IsLittleEndian if needed and handle 
accordingly. 
Or iterate over an array in an unsafe manner: 
int[] a = new int[] { 0x123, 0x234, 0x345, 0x456 }; 
ref int r1 = ref Unsafe.Add(ref a[0], 1); 
Assert.Equal(0x234, r1); 
ref int r2 = ref Unsafe.Add(ref r1, 2); 
 

Assert.Equal(0x456, r2); 
ref int r3 = ref Unsafe.Add(ref r2, -3); 
Assert.Equal(0x123, r3); 
Or the similar Subtract: 
string[] a = new string[] { "abc", "def", "ghi", "jkl" }; 
ref string r1 = ref Unsafe.Subtract(ref a[0], -2); 
Assert.Equal("ghi", r1); 
ref string r2 = ref Unsafe.Subtract(ref r1, -1); 
Assert.Equal("jkl", r2); 
ref string r3 = ref Unsafe.Subtract(ref r2, 3); 
Assert.Equal("abc", r3); 
Additionally, one can check if two ref values are the same i.e. same address: 
long[] a = new long[2]; 
Assert.True(Unsafe.AreSame(ref a[0], ref a[0])); 
Assert.False(Unsafe.AreSame(ref a[0], ref a[1])); 
Links 
Roslyn Github Issue 
System.Runtime.CompilerServices.Unsafe on github 

0 Comment's

Comment Form

Submit Comment