Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么这里不强制使用'ref'关键字?_C# - Fatal编程技术网

C# 为什么这里不强制使用'ref'关键字?

C# 为什么这里不强制使用'ref'关键字?,c#,C#,我显然不太理解ref和参数的范围。有人能告诉我为什么这个代码有效吗?如何将dt发送到函数中(我的意思是它将成为一个参数,范围将作为局部变量,对吗?)。那么为什么在调用fill()之后填充(填充)了dt 所以我的第一个想法是,我只是用fill()发送一个对dt的引用,但是我不理解ref关键字。我以为我们就是为了这个。。当参数是按类型的值时,是否只需使用ref var dt = new DataTable(); using (var cmd = new MySqlCommand(cmdText, c

我显然不太理解
ref
和参数的范围。有人能告诉我为什么这个代码有效吗?如何将
dt
发送到函数中(我的意思是它将成为一个参数,范围将作为局部变量,对吗?)。那么为什么在调用
fill()
之后填充(填充)了
dt

所以我的第一个想法是,我只是用
fill()
发送一个对
dt
的引用,但是我不理解
ref
关键字。我以为我们就是为了这个。。当参数是按类型的值时,是否只需使用
ref

var dt = new DataTable();
using (var cmd = new MySqlCommand(cmdText, connection))
using (var adapter = new MySqlDataAdapter())
{
    adapter.SelectCommand = cmd;
    adapter.Fill(dt); // <---why is ref not needed here?
}
return dt;
var dt=new DataTable();
使用(var cmd=new MySqlCommand(cmdText,connection))
使用(var adapter=new MySqlDataAdapter())
{
adapter.SelectCommand=cmd;

adapter.Fill(dt);/
ref
是在更改引用时使用的命令,而不是引用实例时使用的命令。因此,您可以在不使用
ref
的情况下修改引用实例,但是当您要引用另一个对象时,必须使用
ref

说了这个
Fill
只会修改传递给它的内容,它不会创建一个新的
数据表

另一方面,如果要返回另一个实例,则必须使用
ref

void DoSomething(ref dt)
{
    dt = new DataTable();
    // do something with the new table
}

现在您有两个表,一个被传递给
DoSomething
,另一个是在该方法中创建的,与前者没有任何共同之处。但是调用代码现在引用了新实例,原始引用丢失了。

ref
在更改时将使用e引用,而不是引用的实例。因此,您可以修改引用的实例,而无需使用
ref
,但是,当您想要引用另一个对象时,您必须使用
ref
DataTable
是引用类型,因此它已经通过引用传递。如果您想要精确,请使用va传递引用lue.添加另一个
ref
将通过引用传递引用,允许您更改
dt
引用的内容。间接!对整个家庭来说都很有趣。@himbrombere是的,在说了一些错误、混乱和误导的话之后。这就像说,“橙色是紫色的,但如果你想准确地说,它实际上是橙色的”。继续纠正自己并不会使明显错误的陈述更加正确,也不会减少误导或混淆。正确的思考方法是不要认为
ref
与“引用”有任何关系“。假设关键字不是
ref
,而是
alias
,它变得更加清晰。
ref
只是表示“这个变量是ref'd变量的另一个名称”。当你说
int x=123;M(ref x);
时,我们有
void M(ref int y)
这只是意味着
y
是变量
x
的另一个名称-它是一个别名。为了更深入地了解引用和值,我推荐刘易斯·卡罗尔的《通过观察镜》第8章。虽然我明白了Servy的观点,但我坚持我的评论,因为它有一些解释价值,实际上并不是正确和准确的关于C#语义的se陈述。幸运的是,这个问题有一个完整答案的副本。(顺便说一句,“颜色”是一个奇妙的准物理性质,你可以深入到兔子洞的深处,了解它与我们天真的理解之间的关系,所以这很贴切。)因此,当我传递类型为reference的对象时,我不需要使用
ref
,除非该引用在函数中是新的。您对它进行了更好的描述,但我认为我得到了它。从某种意义上说,该对象是“新的”所以我不知道整个过程中的引用。但是什么时候或者为什么你想/需要发送一些新的参数呢?在不总是这样的情况下,或者类似的情况下?@radbyx
ref
-当你的方法返回多个东西时,使用一个参数可能是有用的。而这也可以通过使用
ou来实现t
-参数,
ref
可以在覆盖引用之前由
DoSomething
使用。因此,您可以调用其任何成员,然后引用另一个实例。