我正在创建一个函数,我需要传递一个对象,以便它可以被函数修改。有什么区别:
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的例子。现在,你们都可以离开裁判了。
在下面提到的例子中,当我注释//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告诉编译器对象在进入函数之前已经初始化,而out告诉编译器对象将在函数内部初始化。
所以当ref是双向的,out是唯一的。
我要试着解释一下:
我想我们理解了值类型是如何工作的,对吧?值类型是(int, long, struct等)。当你将它们发送到一个没有ref命令的函数时,它会复制数据。在函数中对该数据所做的任何操作都只会影响副本,而不会影响原始数据。ref命令发送的是实际数据,任何变化都会影响函数外部的数据。
好了,让人困惑的部分,引用类型:
让我们创建一个引用类型:
List<string> someobject = new List<string>()
当你新建someobject时,会创建两部分:
存储某对象数据的内存块。 指向该块的引用(指针) 的数据。
现在,当你发送someobject到一个没有引用的方法时,它复制的是引用指针,而不是数据。现在你得到了这个:
(outside method) reference1 => someobject
(inside method) reference2 => someobject
两个引用指向同一个对象。如果你使用reference2修改某个对象的属性,它将影响由reference1指向的相同数据。
(inside method) reference2.Add("SomeString");
(outside method) reference1[0] == "SomeString" //this is true
如果你清空了reference2或将其指向新的数据,它不会影响reference1和reference1所指向的数据。
(inside method) reference2 = new List<string>();
(outside method) reference1 != null; reference1[0] == "SomeString" //this is true
The references are now pointing like this:
reference2 => new List<string>()
reference1 => someobject
当你将someobject by ref发送给方法时会发生什么? 对某个对象的实际引用被发送给方法。所以你现在只有一个数据引用:
(outside method) reference1 => someobject;
(inside method) reference1 => someobject;
但这意味着什么呢?它的作用与不通过ref发送someobject完全相同,除了两件主要的事情:
1)当你清空方法内部的引用时,它也会清空方法外部的引用。
(inside method) reference1 = null;
(outside method) reference1 == null; //true
2)你现在可以将引用指向一个完全不同的数据位置,函数外部的引用现在将指向新的数据位置。
(inside method) reference1 = new List<string>();
(outside method) reference1.Count == 0; //this is true
Ref和out的行为类似,只是有一些不同。
引用变量必须在使用前初始化。Out变量无需赋值即可使用 Out形参必须被使用它的函数视为未赋值。因此,我们可以在调用代码中使用初始化的out形参,但该值将在函数执行时丢失。
public static void Main(string[] args)
{
//int a=10;
//change(ref a);
//Console.WriteLine(a);
// Console.Read();
int b;
change2(out b);
Console.WriteLine(b);
Console.Read();
}
// static void change(ref int a)
//{
// a = 20;
//}
static void change2(out int b)
{
b = 20;
}
你可以检查这段代码,它会向你描述它的完全不同 当你使用“ref”时,这意味着你已经初始化了int/string
但 当你使用out的时候 无论你是否初始化int/string,它都适用于这两种情况 但是u必须在函数中初始化int/string
如果你想将参数作为引用传递,那么你应该在将参数传递给函数之前初始化它,否则编译器本身会显示错误。但是对于out形参,您不需要在将对象形参传递给方法之前初始化它。可以在调用方法本身中初始化对象。