我正在创建一个函数,我需要传递一个对象,以便它可以被函数修改。有什么区别:
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通过reference传递,hense;
class Program
{
public static void Main(string[] args)
{
var original = new ObjectWithMememberList(3);
Console.WriteLine(original.MyList.Capacity); // 3
ChangeList(original.MyList);
Console.WriteLine(original.MyList.Capacity); // 3
}
static void ChangeList(List<int> vr)
{
vr = new List<int>(2);
}
}
but:
class Program
{
public static void Main(string[] args)
{
var original = new ObjectWithMememberList(3);
Console.WriteLine(original.MyList.Capacity); // 3
ChangeList(ref original.MyList);
Console.WriteLine(original.MyList.Capacity); // 2
}
static void ChangeList(ref List<int> vr)
{
vr = new List<int>(2);
}
}
out也是一样。 2. Ref参数必须是一个可赋值变量。 hense:
ChangeList(ref new List<int>()); // Compile Error [might not be initialized before accessing]
but:
List<int> xs;
ChangeList(out xs); // Compiles
其他回答
Ref和out的行为类似,只是有一些不同。
引用变量必须在使用前初始化。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; }
}
扩展狗和猫的例子。带有ref的第二个方法更改调用者引用的对象。所以叫“猫”!!
public static void Foo()
{
MyClass myObject = new MyClass();
myObject.Name = "Dog";
Bar(myObject);
Console.WriteLine(myObject.Name); // Writes "Dog".
Bar(ref myObject);
Console.WriteLine(myObject.Name); // Writes "Cat".
}
public static void Bar(MyClass someObject)
{
MyClass myTempObject = new MyClass();
myTempObject.Name = "Cat";
someObject = myTempObject;
}
public static void Bar(ref MyClass someObject)
{
MyClass myTempObject = new MyClass();
myTempObject.Name = "Cat";
someObject = myTempObject;
}
对于那些以身作则的人(比如我),以下是安东尼·科索夫所说的。
我创建了一些ref、out和其他例子来说明这一点。我并没有介绍最佳实践,只是举例来理解它们之间的差异。
https://gist.github.com/2upmedia/6d98a57b68d849ee7091