What's the difference between the 'ref' and 'out' keywords?

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:

  1. The value is already set and
  2. The method can read and modify it.

The out modifier means that:

  1. The Value isn't set and can't be read by the method until it is set.   就算在进入方法前,设置了值,也是无效的
  2. 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,就赋值初始值