Scr*_*cre 18 c# pass-by-reference pass-by-value
从C/C++迈出C#世界的第一步,细节上有点模糊.据我所知,类默认通过引用传递,但是例如.列出<string>,如:
void DoStuff(List<string> strs)
{
//do stuff with the list of strings
}
Run Code Online (Sandbox Code Playgroud)
和其他地方
List<string> sl = new List<string>();
//next fill list in a loop etc. and then do stuff with it:
DoStuff(sl);
Run Code Online (Sandbox Code Playgroud)
是SL在这种情况下按引用传递或者是副本上进行,这样我需要重新定义,如工人功能
void DoStuff(ref List<string> strs)实际上是对sl本身采取行动而不是副本?
底层的事情始终是:值类型是按值传递的,而引用类型是“按引用传递的”(引用是因为引用的值实际上是按值传递的,但大多数人为了简洁而忽略了这一点)。
协调ref关键字与引用的最简单方法是:引用类型的引用按值传递。在标准情况下,这具有简单地将对列表(而不是整个列表)的引用传递给方法的效果。
当在引用类型上使用关键字ref时,它在语义上传递对引用的引用(我真的很难不说“指向指针的指针”)。
如果您的方法要将ref参数重新分配给新对象,则调用者也会看到这个新分配。如果没有ref关键字,该方法将简单地重新分配引用值的本地副本,并且调用者仍然拥有对其原始对象的引用。
上面的解释无耻地摘自Jon Skeet 关于该主题的文章:
这种差异对于理解 C# 中的参数传递绝对至关重要,这就是为什么我认为说对象默认情况下通过引用传递而不是对象引用默认情况下通过值传递的正确说法是非常令人困惑的。
ref仅当您打算重新分配参数并使调用者可见时才需要该关键字。在大多数情况下,您会发现不需要它。您DoStuff可以重写以删除它,并且仍然成功地按值传递对列表的引用:
void DoSomething(List<string> strs)
{
strs.Add("Hello");
}
Run Code Online (Sandbox Code Playgroud)
除了其他答案之外,了解 ref 的行为非常重要
这是一些用于演示目的的示例代码
static void Main(string[] args)
{
List<string> lstStr = new List<string>();
lstStr.Add("First");
lstStr.Add("Second");
Alter(lstStr);
//Alter(ref lstStr);
Console.WriteLine("---From Main---");
foreach (string s in lstStr)
{
Console.WriteLine(s);
}
Alter2(ref lstStr);
Console.WriteLine("---From Main after passed by ref---");
foreach (string s in lstStr)
{
Console.WriteLine(s);
}
Console.ReadKey();
}
static void Alter(List<string> lstStr2)
{
lstStr2.Add("Third");
Console.WriteLine("----From Alter----");
foreach (string s in lstStr2)
{
Console.WriteLine(s);
}
lstStr2 = new List<string>();
lstStr2.Add("Something new");
Console.WriteLine("----From Alter - after the local var is assigned somthing else----");
foreach (string s in lstStr2)
{
Console.WriteLine(s);
}
}
static void Alter2(ref List<string> lstStr2)
{
lstStr2 = new List<string>();
lstStr2.Add("Something new from alter 2");
Console.WriteLine("----From Alter2 - after the local var is assigned new list----");
foreach (string s in lstStr2)
{
Console.WriteLine(s);
}
}
//----From Alter----
//First
//Second
//Third
//----From Alter - after the local var is assigned somthing else----
// Something new
// ---From Main---
// First
// Second
// Third
// ----From Alter2 - after the local var is assigned new list----
// Something new from alter 2
// ---From Main after passed by ref---
// Something new from alter 2
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
39928 次 |
| 最近记录: |