Why does C# require ‘ref’ and ‘out’ at both definition and use?

(question from a customer)

If you use ‘ref’ or ‘out’ on a method parameter:

class Test
    public void Process(ref int t)

when you call it you need to specify ‘ref’:

Test t = new Test();
int val = 5;

t.Process(ref val);

We require you to include ‘ref’ or ‘out’ to improve the readability of your code. Anybody who looks at the call above can tell that the value of val might be changed during the call. Otherwise, you’d have to find the definition, which would be much more difficult.

[Update: Ferris asks “why can’t you use ref with a property?” As Daniel points out, this could lead to some problems with your code, especially in multi-threaded cases. The compiler could handle those cases, but only through synchronization (at least in the general case), which wouldn’t do good things for performance. I think we made the right choice not trying to do this in the compiler.

Oh, and Ferris, it’s really hard to take you serious with that name…]

[Update: Richard asks “Why do I have to have a SecurityPermission in my manifest if I use unsafe to define a parameter as a pointer, but not if I define it as a ref?”

Calling Interop code also requires permissions – SecurityPermission IIRC – which means that there isn’t a real difference in the amount of permission required to run the code.]

Comments (15)

  1. George Chernyha says:

    This reminds me of having to declare an INOUT argument type for SQL Server stored procedures. The C# team must be harboring some ex-SQL Server/Yukon devlopers. 🙂

  2. Eric, I agree about readability. In C++, you could create reference parameters by defining a method like:

    void Method(int& x){..}

    where x could be changed during the call, and when you call it:

    int i;


    You’d have no idea that the method could change the value of x.

    The out and ref approaches are infinitely better, IMHO.


  3. senkwe says:

    I remember it used to irritate me quite a bit. We’re buddies now.

  4. Ferris Beuller says:

    Im all for readability but here is one niggling issue I find.

    On the abstraction of methods into properties we treat the get_ prop as a field yet we cannot treat the set_ prop as a field, ie., we can pass a get_ as a parameter etc like we would a field, yet we cannot pass a set_ byref to have it set like a field. Why not?

    To me this is the most natural way of treating a property.

  5. Ferris Beuller says:

    How often have you seen code like..

    int tempVal = 0;

    obj.someMethod(ref tempVal);

    someObj.someProp = tempVal;

    If you had this abstracted properly for a set prop then we could save the extra vampire code by..

    obj.someMethod(ref someObj.someProp);

    and the compiler would generate the tempVal for us like it does all other abstractions (foreach abstracts IEnumerator etc)

  6. Ferris Beuller says:

    And dont give me lame excuses saying properties are methods, yes yes thats the lower level and why we have the property abstraction yet you do a half arsed implementation and didnt do the set abstraction.

    Its easy to do by having the compiler generate the tempVal.

  7. Daniel Turini says:

    Ferris, your method can lead to problems on multithreaded code, as you’re not passing a "real" reference to someObj.someProp. Even single-threaded code can have a hard time with your approach.

    Just imagine obj.someMethod coded as this

    void someMethod(ref int val)


    val = 5;



    now, do this (using your "automatic temporaries" approach):

    someObj.someProp = 0;



    If someProp is a field, no problem, the code prints 5 and 5. If someProp is a property the code prints 0 and 5.

    This will reduce code readability, as it’s not obvious when the value is changing.

  8. Ferris Beuller says:

    Well why cant the compiler handle this.

    Thats what its there for.

    Why bother abstracting properties when we only do a half arsed job with the get on a parameter only.

  9. Ferris Beuller says:

    Well it can use whatever approach it wants under the hood, doesnt have to be a temporary variable, that part I couldnt give a donkey about.

    you forgot the obj.someMethod(out someObj.someProp);

    r using a ref keyword.

    It will change the value once it goes out of scope and returns from teh method call, duh. Same rules apply as a parameter is changed.

  10. Eric,

    What about this:

    -I’ve a Dll-based method:

    __declspec(dllexport) void APIENTRY MethodTakesPointer(int* i);

    -I can invoke it using a pointer-based declaration in managed code:

    unsafe static extern void MethodTakesPointer(int* i);

    which creates the following IL declaration:

    .method private hidebysig static pinvokeimpl("Win32Lib" winapi)

    void MethodTakesPointer(int32* i) cil managed preservesig



    and can be used to call the target with:

    int i;


    -or I can use a ref-based declaration:

    static extern void MethodTakesPointer(ref int i);

    which generates a subtly different IL declaration:

    .method private hidebysig static pinvokeimpl("Win32Lib" winapi)

    void MethodTakesPointer(int32& i) cil managed preservesig



    and use it to call the target with:

    int i;

    MethodTakesPointer(ref i);

    Both appear to work (callee modifies the int to the expected value), but only the first one carries the stigma of the SecurityPermission added to the caller’s manifest because of /unsafe.

    Should the 2nd one work, and if it should, doesn’t that negate part of the value of having the SecurityPermission in the manifest of the caller?

    Really curious about this one.



  11. Richard,

    Yes it should work. I’m not sure why you think it negates the value of the SecurityPermission.

  12. RichB says:

    I love C# because it forces me to explicitly declare my intentions.

    I also love it because it makes it more time-consuming and difficult to write ByRef-style parameters – something which should be abolished from the repertoire of every proficient OO developer.

  13. Reply to Mattias who said:

    >Yes it should work. I’m not sure why you think it negates the value of the SecurityPermission

    I think you misunderstood me. I don’t think it negates the value of the SecurityPermission at all. But it raises the question: shouldn’t the Permission be in the manifest in both cases?

    Eric: even if the MyComputer Zone enables Interop, shouldn’t the use of ‘ref’ parameters in an Interop method generate a SecurityPermission in the caller’s Manifest the same way that using a pointer parameter does?

    Why generate the Permission in one case and not the other?



  14. Thomas Eyde says:

    I don’t get the readability part. There are several solutions to that problem, there’s no need to create a more verbose language. We will not write any code without intention, right? So what does this code do?

    string id;


    User newUser = new User(id, "Thomas Eyde");


    Is it so hard to see that GetUniqueId updates the id? Does it really matter? I knew when I wrote it and as long as it works, I will not look at it again.

    If it should fail, I would use intellisense to reveal the signature "public void GetUniqueId(out int newUniqueId)"

    By the way: Both ref and out? Please give me a break! How stupid are we anyway? Loose the "out". How often will a programmer forget to update a return parameter, anyway?

  15. Garfield says:

    We have a com object written in C++ with OUT parameters. With VB we can ByRef them, but in C# the compiler only permits the use of "out".

    Unfortunately, routines pass values which

    must first be checked, and the compiler throws

    this out with a "use of unassigned variable" error. There is no way around this!

    MyMethod(out string MyParameter)


    if (!StringIsValid(MyParameter)) <–Error!


    MyParameter = "ValidString";