Tech Off Thread

7 posts

Forum Read Only

This forum has been made read only by the site admins. No new threads or comments can be added.

differnence between Ref and Out

Back to Forum: Tech Off
  • User profile image
    peoples

    Hi, I am learning C# and i was wondering when you would use Out as opposed to Ref in a function call. I don't quite understand. I understand why & when you would use Ref but not Out.

     

    Gregor

  • User profile image
    BitFlipper

    In C#, ref and out are the same, except that if you use out, the called method is required to initialize the value before it can return.

    Use out if the called method doesn't care about the parameter's initial value, and use ref if you want to pass a value both in (the called method actually uses the value) and out (the calling method wants to use the updated value).

    In neither case is the value boxed/unboxed. Internally it merely uses a pointer to the value instead of passing it by value (just like passing by ref in C++).

     

  • User profile image
    Sven Groot

    As BitFlipper said, with out the method is required to set a value before it returns.

    // This function won't compile because value isn't set on all code paths
    void Foo(out int value)
    {
    }
    
    // Whereas this is fine even though value isn't set.
    void Bar(ref int value)
    {
    }

    It also makes a difference on the calling side, however. Out parameters don't need to be initialized before passing them to a function:

    void Test()
    {
        int n;
        SomeFunc(ref n); // This won't compile; n is uninitialized.
        SomeOtherFunc(out n); // Whereas this is fine, even if n is uninitialized
        // n is guaranteed to have a value after the call to Foo, because
        // the function is required to assign it a value before returning.
    }

    Basically, use ref when you need to pass a value in and get a different value out, and use out when you only need to get a value out.

    In general, try to avoid using ref/out parameters, because they lead to code that doesn't compose well. Sometimes it's unavoidable, but always try to find an alternative solution.

    Just in case (since this is a common point of confusion): you do not need to use ref to be able to modify a parameter of a reference type (class) inside a function. With reference types you already passing a reference. Passing a reference type with ref means you pass a reference to a reference, which is only needed if you want to return a completely different instance to the caller.

    class Foo
    {
        public string Bar { get; set; }
    }
    
    void ModifyFoo(Foo value)
    {
        value.Bar = "hello"; // The caller will see this change, even without ref
        value = new Foo(); // But the caller will *not* see this change; it doesn't get the new instance.
    }
    
    void ReplaceFoo(ref Foo value)
    {
        value = new Foo(); // With ref, the caller will see this change and get the new instance.
        // I could've used out here, since we don't use the value that was passed in.
    }

  • User profile image
    wkempf

    @Sven Groot: Sorry, "references types are already passed by reference" is simply wrong. Without the use of ref or out you are passing by value. What you are passing by value is a reference. It's a bit of a nit, because the rest of what you said is correct, but this is one that really should be understood.

  • User profile image
    Sven Groot

    @wkempf: Thanks, I updated my wording a bit.

  • User profile image
    peoples

    Ok thanks alot Smiley

  • User profile image
    evildictait​or

    "out object result" is a way of saying that the function will generate a new object that the caller can play with if the method is called. It's basically an additional return type that the method has, so it can return more than one thing at a time.

    "ref object result" means you're going to give the method a variable, but allow the method to not only change the variable by calling its methods and settings its fields, but also allow the method to set the variable from which object came. This is like a sub-function setting a local variable in a parent method.

     

    Consider the following code:

    object myObj = new object(); // line 1
    foo(ref myObj); // line 2
    // line 3

    line1 initializes myObj. Line2 potentially modifies or changes myObj (it behaves like myObj = someFunc(myObj), it could either change myObj and return myObj, it could return null or it could return an entirely new object).

     

    Consider now the following code:

    object myObj = new object(); // line 1
    foo(out myObj); // line 2
    // line 3

    line1 initializes myObj as before. Line2 now throws away the previous value of myObj. During line2 myObj is set to a completely new value. This is behaving like myObj = someFunc().

Conversation locked

This conversation has been locked by the site admins. No new comments can be made.