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);
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.
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.
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.
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.
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.
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.
Eric Lippert explains in Why do ref and out parameters not allow type variation?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With