This page is a guide to how parameters should be passed in C#.
Rules for value types
valueTypeName variableName | The normal way of passing. |
ref variableName | Callee is invited to modify in-place. |
out variableName | Callee must modify in-place. |
Rules for reference types
ReferenceTypeName variableName | Callee may modify in place |
ref ReferenceTypeName variableName | Callee is invited to modify in place or change what is referred to. |
out ReferenceTypeName variableName | Callee must modify in place. |
Examples
There follows a sketch of the declaration of a class with many methods, each handling different parameter types, passed in different ways. Look at each example below and refer back to the declaration of class G, to see the parameter declaration relevant to the call being made.
class G
{
...
void useValueOf(string s);
void modifyIfDesired(ref string s);
void assignTo(out string s);
void modifyIfDesired(object o);
void modificationsWillBeIgnored(object copyOfO);
void modifyIfDesiredOrPointToADifferentObject(ref object o);
void assignTo(out object o);
}
Pass primitive type
g.useValueOf("hello");
string s = "world";
g.useValueOf(s);
// s must still be "world"
Pass primitive type when you want to allow it to be modified
string s = "bunnies";
g.modifyIfDesired(s);
// s might have changed
Pass primitive type, requiring that it is assigned to
string s;
g.modifyOrDie(s);
// Compiler ensures that callee assigns to s - gives error if not.
Pass reference type, callee may modify
Note that it is impolite for the callee to modify the argument. You should only modify an argument when it is passed as ‘ref’ or ‘out’. People don’t expect you to modify arguments which are passed ‘by value’, even though they really are references.
MyClass obj = new MyClass();
g.modifyIfDesired(obj);
Pass reference type
We really don’t want to see any changes the callee makes.
MyClass obj = new MyClass(); // implements ICloneable.
g.modificationsWillBeIgnored(obj.Clone());
Pass reference type
We are telling the callee that modifications are expected, though it doesn’t have to make any if it doesn’t want to. The callee may point our reference at a different object! Doing so is not a normal thing to do, however, and should be used only when absolutely necessary for some trickery - preferably with a mention in the method documentation.
MyClass obj = new MyClass();
g.modifyIfDesiredOrPointToADifferentObject(obj);
Pass reference type, callee must assign to it
MyClass obj;
g.assignTo(obj);
// obj has been assigned a value. Of course, it might have been assigned null!
No comments:
Post a Comment