C# – How to pass this by ref in C#

cnetreferencethis

In a class (ClassA) of mine I want to create a related instance of another class (ClassB) providing it with a reference to the object who has initiated it's creation. So I've provided ClassB with a construcror taking a (ref ClassB master) argument. But in ClassA I can't just call var slave = new ClassB(ref this). How to implement this?

Best Answer

The ref keyword causes Pass by Reference semantics - that is, if the variable is re-assigned in the called function, it will re-assign the variable in the caller as well.

Obviously, this only works if a variable2 (which can be re-assigne to) is directly passed as the argument and will not work if an arbitrary expression is passed. In this case, this is not a variable, rather a special expression which cannot be re-assigned, and so cannot be used.

As such, this would work: (But please see other answers and keep reading as to why this is likely not required and/or just silly.)

var me = this;
var slave = new ClassB(ref me);

However, Pass by reference should not be confused with Pass by Object [Sharing]1 semantics. Pass by Object means that if an object is passed, that object is passed: the object is not copied/cloned/duplicated. If the object is mutated then the object is mutated. All Reference Types have Pass by Object semantics in C# unless either ref or out are used. (The class keyword declares a new reference type, as in the case in the post).

On the other hand, Value Types (e.g. struct), including int and Guid and KeyValuePair<K,V>, have Pass by Value semantics - in this case a copy is made and thus, if the value is modified, only the value struct (which is a copy) changes.

Happy coding


1 Underneath C#/.NET achieves Pass by Object by passing a reference to an object by Value. However, the rules above correctly describe the observable semantics and effects.

2 Unlike C#, which only allows variables to be used with ref, VB.NET allows Properties to be used. The VB.NET compiler automatically creates a temporary variable and implicit reading/writing instructions of the property during compilation.