Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Objects, parameters and the ref keyword in C#

Tags:

c#

.net

When the formal argument of a method is of type 'object' it is possible, through inheritance, for the actual argument to be any object type. Once in the method the object can be cast to the type expected. All's fine.

If, however, the signature of the method has a formal argument of 'object', using the ref keyword i.e. methodname(ref object), the compiler throws an error stating that:

"The best overloaded method match for 'ByRefTest.Program.changeMeByRef(ref object)' has some invalid arguments. "Argument '1': cannot convert from 'ref ByRefTest.Person' to 'ref object'"

The difference between using or not using the ref keword when passing objects as parameters is explained very well in A. Friedman's blog http://crazorsharp.blogspot.com/2009/07/passing-objects-using-ref-keywordwait.html , but why is it not possible to pass a custom type as an actual argument when the formal argument of type 'object' uses the ref keyword?

As an example:

class Program
{
    static void Main(string[] args)
    {
        Person p = new Person();

        changeMe(p); // compiles
        changeMeByRef(ref p); // throws error

        object pObject = (object)p;
        changeMeByRef(ref pObject); // compiles
    }


    public static void changeMeByRef(ref object obj)
    {
        Person p = (Person)obj;
    }

    public static void changeMe(object obj)
    {
        Person p = (Person)obj;

    }
}

public class Person
{
}

Thanks.

ps I just changed the signature to:

public static void changeMeByRef<T>(ref T obj) where T : Person

this compiles for changeMeByRef(ref p);

like image 506
iWeasel Avatar asked Sep 30 '09 13:09

iWeasel


People also ask

What is ref keyword?

The ref keyword indicates that a variable is a reference, or an alias for another object. It's used in five different contexts: In a method signature and in a method call, to pass an argument to a method by reference.

What is ref parameter?

A reference parameter is a reference to a memory location of a variable. When you pass parameters by reference, unlike value parameters, a new storage location is not created for these parameters. The reference parameters represent the same memory location as the actual parameters that are supplied to the method.

What is the difference between ref and out parameters?

ref is used to state that the parameter passed may be modified by the method. in is used to state that the parameter passed cannot be modified by the method. out is used to state that the parameter passed must be modified by the method.

Why ref is used in C#?

The ref keyword in C# is used for passing or returning references of values to or from Methods. Basically, it means that any change made to a value that is passed by reference will reflect this change since you are modifying the value at the address and not just the value.


3 Answers

Because the method might change the parameter to have a value of different type, in violation of the type of the variable used for the argument. Simple example:

public void Foo(ref object x)
{
    x = "hello";
}

...

// This doesn't compile, fortunately.
Stream y = null;
Foo(ref y);

What's the value of y after the assignment in the method? It should be a string - but that violates the type of the variable. That would be a Very Bad Thing, completely violating type safety. This is the same kind of reason for the generic invariance of IList<T> even in .NET 4.0.

Eric Lippert recently blogged about the invariance of ref in more detail.

like image 173
Jon Skeet Avatar answered Sep 24 '22 10:09

Jon Skeet


Because the ref parameter work both ways. You can assign the parameter to an arbitrary object inside your function, and the calling code needs to handle it.

like image 37
Grzenio Avatar answered Sep 24 '22 10:09

Grzenio


Eric Lippert explains in Why do ref and out parameters not allow type variation?

like image 29
Dzmitry Huba Avatar answered Sep 24 '22 10:09

Dzmitry Huba