我正在创建一个函数,我需要传递一个对象,以便它可以被函数修改。有什么区别:
public void myFunction(ref MyClass someClass)
and
public void myFunction(out MyClass someClass)
我应该用哪个,为什么?
我正在创建一个函数,我需要传递一个对象,以便它可以被函数修改。有什么区别:
public void myFunction(ref MyClass someClass)
and
public void myFunction(out MyClass someClass)
我应该用哪个,为什么?
当前回答
ref和out就像c++中传递引用和传递指针一样。
对于ref,参数必须声明并初始化。
对于out,实参必须声明,但可以初始化,也可以不初始化
double nbr = 6; // if not initialized we get error
double dd = doit.square(ref nbr);
double Half_nbr ; // fine as passed by out, but inside the calling method you initialize it
doit.math_routines(nbr, out Half_nbr);
其他回答
ref修饰符的意思是:
该值已经设置,并且 该方法可以读取和修改它。
out修饰符的意思是:
Value未被设置,并且在设置之前不能被方法读取。 方法必须在返回之前设置它。
它们几乎是一样的——唯一的区别是,作为out形参传递的变量不需要初始化,使用ref形参的方法必须将其设置为某个值。
int x; Foo(out x); // OK
int y; Foo(ref y); // Error
Ref形参用于可能被修改的数据,out形参用于已经使用返回值的函数(例如int.TryParse)的额外输出数据。
Ref和out的行为类似,只是有一些不同。
引用变量必须在使用前初始化。Out变量无需赋值即可使用 Out形参必须被使用它的函数视为未赋值。因此,我们可以在调用代码中使用初始化的out形参,但该值将在函数执行时丢失。
下面是一个同时使用Ref和out的例子。现在,你们都可以离开裁判了。
在下面提到的例子中,当我注释//myRefObj = new myClass {Name = "ref outside called!! ""}; 行,将得到一个错误说“使用未分配的局部变量'myRefObj'”,但没有这样的错误在out。
在哪里使用Ref:当我们调用带有in形参的过程时,该形参将用于存储该过程的输出。
在哪里使用Out:当我们调用一个没有in形参的过程时,相同的参数将用于返回该过程的值。 还要注意输出
public partial class refAndOutUse : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
myClass myRefObj;
myRefObj = new myClass { Name = "ref outside called!! <br/>" };
myRefFunction(ref myRefObj);
Response.Write(myRefObj.Name); //ref inside function
myClass myOutObj;
myOutFunction(out myOutObj);
Response.Write(myOutObj.Name); //out inside function
}
void myRefFunction(ref myClass refObj)
{
refObj.Name = "ref inside function <br/>";
Response.Write(refObj.Name); //ref inside function
}
void myOutFunction(out myClass outObj)
{
outObj = new myClass { Name = "out inside function <br/>" };
Response.Write(outObj.Name); //out inside function
}
}
public class myClass
{
public string Name { get; set; }
}
: return语句只能用于从函数中返回一个值。但是,使用输出参数,可以从一个函数返回两个值。输出参数类似于引用参数,只是它们将数据传输出方法而不是传输到方法中。
下面的例子说明了这一点:
using System;
namespace CalculatorApplication
{
class NumberManipulator
{
public void getValue(out int x )
{
int temp = 5;
x = temp;
}
static void Main(string[] args)
{
NumberManipulator n = new NumberManipulator();
/* local variable definition */
int a = 100;
Console.WriteLine("Before method call, value of a : {0}", a);
/* calling a function to get the value */
n.getValue(out a);
Console.WriteLine("After method call, value of a : {0}", a);
Console.ReadLine();
}
}
}
裁判: 引用形参是对变量内存位置的引用。与值参数不同,通过引用传递参数时,不会为这些参数创建新的存储位置。引用参数表示与提供给方法的实际参数相同的内存位置。
在c#中,使用ref关键字声明引用参数。下面的例子说明了这一点:
using System;
namespace CalculatorApplication
{
class NumberManipulator
{
public void swap(ref int x, ref int y)
{
int temp;
temp = x; /* save the value of x */
x = y; /* put y into x */
y = temp; /* put temp into y */
}
static void Main(string[] args)
{
NumberManipulator n = new NumberManipulator();
/* local variable definition */
int a = 100;
int b = 200;
Console.WriteLine("Before swap, value of a : {0}", a);
Console.WriteLine("Before swap, value of b : {0}", b);
/* calling a function to swap the values */
n.swap(ref a, ref b);
Console.WriteLine("After swap, value of a : {0}", a);
Console.WriteLine("After swap, value of b : {0}", b);
Console.ReadLine();
}
}
}