https://github.com/arturwincenciak/ref-arg
Pass a value type variable by reference as a parameter of a method
https://github.com/arturwincenciak/ref-arg
csharp csharp-code dotnet dotnet-core internals
Last synced: about 2 months ago
JSON representation
Pass a value type variable by reference as a parameter of a method
- Host: GitHub
- URL: https://github.com/arturwincenciak/ref-arg
- Owner: ArturWincenciak
- License: mit
- Created: 2022-12-23T21:47:49.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2022-12-26T01:06:25.000Z (over 3 years ago)
- Last Synced: 2026-02-24T10:50:23.786Z (4 months ago)
- Topics: csharp, csharp-code, dotnet, dotnet-core, internals
- Language: C#
- Homepage: https://teovincentblog.wordpress.com/2022/12/26/ref-returns-ref-locals-ref-arg/
- Size: 26.4 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Ref Arg
## Overview
This repository contains code demonstrating the difference between passing arguments by value and by reference in C#. The code includes examples of passing various types (e.g. int, struct, class) as arguments to methods, and modifying the values of the arguments within the methods.
Blog post: [Ref Returns, Ref Locals, Ref Arg](https://teovincentblog.wordpress.com/2022/12/26/ref-returns-ref-locals-ref-arg)
## Notes
Keep in mind that passing arguments by reference can lead to more difficult to predict code behavior and more difficult debugging. Therefore, caution should be taken and the appropriateness of using reference arguments should be considered.
## Drivers
When writing highly performant applications, it is often beneficial to use value types such as structs instead of reference types like class. This is because structs are stored on the stack rather than the heap, which means the garbage collector has less work to do as it does not need to track and clean up unused structs.
Another technique to improve the performance of your program is to pass value types as reference arguments in methods. This avoids the overhead of copying the bytes of the value into the local scope of the method, especially when working with large value types or frequently calling the method.
## To dive deeper
See the continuation on `ref loclas` and `ref returns` that repo: [Ref-Lokals-Ref-Returns](https://github.com/ArturWincenciak/Ref-Locals-Ref-Returns)
## Output
The code will output the values of various variables before and after they are passed as arguments to methods. This will illustrate the difference between passing by value and by reference, as well as the impact of modifying the values of the arguments within the methods.
```
Alright ref!
Passing an argument by reference.
#01: globalInt = 100
ArgIntMethod #1: argInt = 100
ArgIntMethod #2: argInt = 200
#02: globalInt = 100
ArgRefIntMethod #1: refArgInt = 100
ArgRefIntMethod #2: refArgInt = 200
#03: globalInt = 200
#04: globalStruct = [IntProp: 1000, StrProp: _str_in_struct_, ClassProp: [DoubleProp: 1000.1, StrProp: _str_in_class_, StructInClassProp: [FloatProp: 1000.2]], StructInStructProp: [FloatProp: 1000.3]]
ArgStructMethod: #1: argStruct = [IntProp: 1000, StrProp: _str_in_struct_, ClassProp: [DoubleProp: 1000.1, StrProp: _str_in_class_, StructInClassProp: [FloatProp: 1000.2]], StructInStructProp: [FloatProp: 1000.3]]
ArgStructMethod: #2: argStruct = [IntProp: 2000, StrProp: _str_in_struct_modified_, ClassProp: [DoubleProp: 2000.1, StrProp: _str_in_class_modified_, StructInClassProp: [FloatProp: 2000.2]], StructInStructProp: [FloatProp: 2000.3]]
#05: globalStruct = [IntProp: 1000, StrProp: _str_in_struct_, ClassProp: [DoubleProp: 2000.1, StrProp: _str_in_class_modified_, StructInClassProp: [FloatProp: 2000.2]], StructInStructProp: [FloatProp: 1000.3]]
ArgRefStructMethod: #1: refStruct = [IntProp: 1000, StrProp: _str_in_struct_, ClassProp: [DoubleProp: 2000.1, StrProp: _str_in_class_modified_, StructInClassProp: [FloatProp: 2000.2]], StructInStructProp: [FloatProp: 1000.3]]
ArgRefStructMethod: #2: refStruct = [IntProp: 2000, StrProp: _str_in_struct_modified_, ClassProp: [DoubleProp: 3000.1, StrProp: _str_in_class_modified_modified_, StructInClassProp: [FloatProp: 3000.2]], StructInStructProp: [FloatProp: 2000.3]]
#06: globalStruct = [IntProp: 2000, StrProp: _str_in_struct_modified_, ClassProp: [DoubleProp: 3000.1, StrProp: _str_in_class_modified_modified_, StructInClassProp: [FloatProp: 3000.2]], StructInStructProp: [FloatProp: 2000.3]]
#07: globalClass = [DoubleProp: 10.1, StrProp: _str_, StructInClassProp: [FloatProp: 10.2]]
EditPropsOfArgClassMethod: #1: argClass = [DoubleProp: 10.1, StrProp: _str_, StructInClassProp: [FloatProp: 10.2]]
EditPropsOfArgClassMethod: #2: argClass = [DoubleProp: 20.1, StrProp: modified_, StructInClassProp: [FloatProp: 20.2]]
#08: globalClass = [DoubleProp: 20.1, StrProp: modified_, StructInClassProp: [FloatProp: 20.2]]
EditPropsOfArgRefClassMethod: #1: refClass = [DoubleProp: 20.1, StrProp: modified_, StructInClassProp: [FloatProp: 20.2]]
EditPropsOfArgRefClassMethod: #2: refClass = [DoubleProp: 30.1, StrProp: modified_, StructInClassProp: [FloatProp: 30.2]]
#09: globalClass = [DoubleProp: 30.1, StrProp: modified_, StructInClassProp: [FloatProp: 30.2]]
CreateNewUsingArgClassMethod: #1: argClass = [DoubleProp: 30.1, StrProp: modified_, StructInClassProp: [FloatProp: 30.2]]
CreateNewUsingArgClassMethod: #2: argClass = [DoubleProp: 123456789, StrProp: _the_new_one_without_ref_, StructInClassProp: [FloatProp: 123456790]]
#10: globalClass = [DoubleProp: 30.1, StrProp: modified_, StructInClassProp: [FloatProp: 30.2]]
CreateNewUsingArgRefClassMethod: #1: refClass = [DoubleProp: 30.1, StrProp: modified_, StructInClassProp: [FloatProp: 30.2]]
CreateNewUsingArgRefClassMethod: #2: refClass = [DoubleProp: 987654321, StrProp: _the_new_one_by_ref_, StructInClassProp: [FloatProp: 987654340]]
#11: globalClass = [DoubleProp: 987654321, StrProp: _the_new_one_by_ref_, StructInClassProp: [FloatProp: 987654340]]
```