I'm creating a function where I need to pass an object so that it can be modified by the function. What is the difference between:
public void myFunction(ref MyClass someClass)
and
public void myFunction(out MyClass someClass)
Which should I use and why?
评论
You: I need to pass an object so that it can be modified It looks like MyClass
would be a class
type, i.e. a reference type. In that case, the object you pass can be modified by the myFunction
even with no ref
/out
keyword. myFunction
will receive a new reference that points to the same object, and it can modify that same object as much as it wants. The difference the ref
keyword would make, would be that myFunction
received the same reference to the same object. That would be important only if myFunction
were to change the reference to point to another object.
回答1
ref
tells the compiler that the object is initialized before entering the function, while out
tells the compiler that the object will be initialized inside the function.
So while ref
is two-ways, out
is out-only.
回答2
The ref
modifier means that:
- The value is already set and
- The method can read and modify it.
The out
modifier means that:
- The Value isn't set and can't be read by the method until it is set. 就算在进入方法前,设置了值,也是无效的
- The method must set it before returning.
This answer most clearly and concisely简洁地 explains the restrictions that the compiler imposes when using the out keyword as opposed to the ref keyword.
Is using the 'ref' keyword for string parameters in methods good for performance in C#? [duplicate]
When I use this method, the compiler creates a copy of the text for the method, right?
No, it doesn't. string
is a reference type, and the compiler will create a new stack variable which points to the same string
represented at a given memory address. It won't copy the string.
When you use ref
on a reference type, there won't be a copy of the pointer to the string
created. It will simply pass the already created reference. This is useful only when you want to create an entirely new string
:
void Main()
{
string s = "hello";
M(s);
Console.WriteLine(s);
M(ref s);
Console.WriteLine(s);
}
public void M(string s)
{
s = "this won't change the original string";
}
public void M(ref string s)
{
s = "this will change the original string";
}
So is it good for performance using ref like this?
The performance gains won't be noticeable. What will happen is other developers getting confused as to why you used ref
to pass the string.
What is the use of “ref” for reference-type variables in C#?
回答1
You can change what foo
points to using y
:
Foo foo = new Foo("1");
void Bar(ref Foo y)
{
y = new Foo("2");
}
Bar(ref foo);
// foo.Name == "2"
so you basically get a reference to the original reference
回答2
Jon Skeet wrote a great article about parameter passing in C#. It details clearly the exact behaviour and usage of passing parameters by value, by reference (ref
), and by output (out
).
Here's an important quote from that page in relation to ref
parameters:
Reference parameters don't pass the values of the variables used in the function member invocation - they use the variables themselves. Rather than creating a new storage location for the variable in the function member declaration, the same storage location is used, so the value of the variable in the function member and the value of the reference parameter will always be the same. Reference parameters need the ref modifier as part of both the declaration and the invocation - that means it's always clear when you're passing something by reference.
I like the analogy类比 of passing your dogs leash to friend for passing a reference by-value... it breaks down quickly though, because I think you would probably notice if your friend traded-up your shih tzu狮子犬,西施犬 to a doberman杜宾犬 before he handed you back the leash
回答3 这里算是一个真实的使用场景,相比修改属性值而言,直接交换引用是最快的
There are cases where you want to modify the actual reference and not the object pointed to:
void Swap<T>(ref T x, ref T y) {
T t = x;
x = y;
y = t;
}
var test = new[] { "0", "1" };
Swap(ref test[0], ref test[1]);
Reference type still needs pass by ref?
When you use the 'ref' keyword it tells the compiler to pass the original reference, not a copy, so you can modify what the reference points to inside of the function. However, the need for this is usually rare and is most often used when you need to return multiple values from a method.
一个方法只能有一个返回值,不使用Tuple的前提下,要返回两个值的话,
Use of 'ref' keyword in C# [duplicate]
There is a lot of confusing misinformation in the answers here. The easiest way to understand this is to abandon the idea that "ref" means "by reference". A better way to think about it is that "ref" means "I want this formal parameter on the callee side to be an alias for a particular variable on the caller side".
When you say
void M(ref int y) { y = 123; }
...
int x = 456;
M(ref x);
that is saying "during the call to M, the formal parameter y on the callee side is another name for the variable x on the caller side". Assigning 123 to y is exactly the same as assigning 123 to x because they are the same variable, a variable with two names.
That's all. Don't think about reference types or value types or whatever, don't think about passing by reference or passing by value. All "ref" means is "temporarily make a second name for this variable".
C# ref keyword usage
When you may replace the original object, you should send him as ref
. If it's just for output and can be uninitialized before calling the function, you'll use out
.
ref对引用类型的唯一适用场景
1.swap
交换2个同类型的变量的值,如果不使用ref,而是通过属性设置来交换,效率就太低了
2.ref传递过来的参数,会被替换掉,并且在替换之前还需要使用到ref变量里面的属性
3.遇到一个特殊情况的,ref传递过来的参数是null,方法里面判断这个参数是null,就赋值初始值