If I have some method that accepts a boolean, and I pass it a property that is a boolean, will that method be referencing the property? Or just the value of what I passed at the time?
-
look at the answer [here](http://stackoverflow.com/questions/1381881/c-sharp-reference-type-still-needs-pass-by-ref) – Jonesopolis Sep 30 '16 at 19:05
-
1I recommend you read Jon Skeet's blog post [Parameter passing in C#](http://www.yoda.arachsys.com/csharp/parameters.html) – juharr Sep 30 '16 at 19:06
-
@Jonesopolis Yeah I definitely didn't look hard enough on this one, but it was worth just asking. Got an answer from someone willing to help out. – Snoop Sep 30 '16 at 19:06
3 Answers
You need to use the ref
keyword to pass by reference in C#. In C#, pass by value is the default. This is a little confusing when you pass a non-immutable class instance, because what you're passing is the value of a reference. When you pass a class reference to a method, without the ref
keyword, the method can change the properties of the instance, but they can't change the caller's reference to that instance. They can't change the caller's reference to refer to a new instance. But with ref
(or out
), they can.
The ref
keyword in C# can't be used with a property. See fiddle for the code below:
Compilation error (line 8, col 15): A property, indexer or dynamic member access may not be passed as an out or ref parameter
C#
using System;
public class Program
{
public static void Main()
{
var c = new C();
F(ref c.P);
}
public static void F(ref int n) { }
public class C
{
public int P { get; set; }
}
}
This is because ref int
is a reference to an int, and a property with a getter and a setter is not an integer. It's code that returns an integer, or can have an integer assigned to it. C# does some magic, but not that much magic. And "magic" is just code generated by the compiler. They could have done that. But they didn't.
I would guess that they wanted to keep it as simple syntactic sugar on a pointer (or whatever thing closely analogous to it) for the sake of runtime efficiency. But that guess could be hilariously wrong.

- 36,786
- 7
- 62
- 114
-
It's actually *conceptually* possible. Properties are treated as variables in other contexts (in that you can assign to them with the assignment operator). VB actually supports the hypothetical feature you described, if memory serves, C# just didn't bother to add it. – Servy Sep 30 '16 at 19:09
-
1@Servy Oh, of course it's conceptually possible -- you can generate code to do pretty much anything (unless it's something you can't generate code to do). – 15ee8f99-57ff-4f92-890c-b56153 Sep 30 '16 at 19:11
-
Well, in your case where it's an auto property it would be possible. But what happens when I change it to `public int P {get{ return DateTime.Now.Millisecond;} set{ //Do nothing } }` you would completely break someone's code by implementing the property. That's why it's not an option. – aquinas Sep 30 '16 at 19:39
-
@aquinas Depends how they implement it. In my limited wisdom, my first thought would be to have `ref n` simply grab the getter and setter for the property and use them -- and generate a simple getter/setter if `n` is a field or a variable. In that case, a no-op setter wouldn't break any expectations it doesn't break already. So you'd get a few "does not behave as expected" questions here, where after pulling teeth to get the code out of them, you'd find that the setter was empty. No setter at all? "Property or indexer P cannot be assigned to -- it is read only". – 15ee8f99-57ff-4f92-890c-b56153 Sep 30 '16 at 19:46
-
@EdPlunkett I think the difficulty with that is that it means that different code has to be generated for the same method depending on what parameter is passed to it. That's pretty significantly different from how methods are currently compiled (where the code generated for a method only depends on the contents of the method). In order to do it right I think the compiler would have to quietly generate a separate overload of the method that took the getter and setter as delegates or something. – Kyle Sep 30 '16 at 20:20
-
@Kyle Not if it's using getter/setter delegates in either case. My thought was that the compiler would generate simple ones to pass in for regular values, much like it generates an enumerator class for `yield return`. There are other cases that escape my memory at the moment. The function knows it's getting a getter and a setter for `int`, doesn't need to care who defined them. Simple enough. It would just cost few more cycles at runtime, I would think. How much more, I don't know. Maybe not enough to worry about. – 15ee8f99-57ff-4f92-890c-b56153 Sep 30 '16 at 20:24
-
@Kyle A certain amount of funny business goes on behind the scenes for local variables referenced in lambdas, for example. That compiler is always sneaking around behind your back. – 15ee8f99-57ff-4f92-890c-b56153 Sep 30 '16 at 20:26
the value of what you passed at the time

- 1,247
- 1
- 9
- 13
-
Okay, kind of what I figured. Because the property would just evaluate similar to how a method would, right? – Snoop Sep 30 '16 at 19:02
-
If needed you could pass a reference to the property by wrapping it in a delegate, which is evaluated within the called function, but there would need to be a good reason to do it. – PhillipH Sep 30 '16 at 19:22
It will be passing the value.
By default, all parameters in C# copy the value. The exception to this is when the property is annotated with out
or ref
, in which case the parameter is actually a reference to the value, rather than the value itself.
While it is possible, in general, to have a parameter passed by reference to a method, you cannot pass the value of a property by reference, it simply isn't supported in C#. If the method you have were annotated with ref
then your code wouldn't compile.

- 202,030
- 26
- 332
- 449