提问人:Brad 提问时间:10/22/2010 最后编辑:one noaBrad 更新时间:11/15/2023 访问量:18443
我可以修改传递的方法参数吗
Can I modify a passed method parameter
问:
我的直觉告诉我不应该做以下事情。我没有收到任何关于它的警告。
void test(DateTime d)
{
d = d.AddDays(2);
//do some thing with d
}
还是这样更合适
void test(DateTime d)
{
DateTime _d = d.AddDays(1);
//do some thing with _d
}
出于某种原因,我总是像第二个示例一样处理传递的参数。 但我不确定这是否真的是 nessesry......也许这只是不合时宜的代码。
我不认为调用方法会使用修改后的值。 任何人都有任何意见
答:
5赞
Aliostad
10/22/2010
#1
您可以更改它,但更改不会返回给调用方。
如果是 ValueType ->则发送对象的副本
如果是 RefernceType ->则对象引用的副本将按值发送。通过这种方式,可以更改对象的属性,但不能更改引用本身 - 调用方无论如何都不会看到更改。
如果发送了 -> 可以更改引用。ref
在 C++ 中,您可以使用来阻止更改,但 C# 没有。这只是为了防止程序员错误地尝试更改它 - 取决于在哪里使用。const
const
评论
0赞
Harper Shelby
10/22/2010
这取决于细节。在这个非常具体的示例中,由于 DateTime 是一个结构,并且具有值语义,因此这是真的。其他具有引用语义的参数会将该更改反映回调用方。
0赞
Jon Skeet
10/22/2010
@Harper:如果 OP 更改了参数的值,而不是对参数值所引用的对象进行更改,则不会。有关这两者之间差异的示例,请参阅我的回答。
0赞
Anthony Pegram
10/22/2010
@Harper,除非它是专门的(或)参数,否则不会反映在结构或类的调用站点上。对引用类型的成员执行的操作将反映,而对引用本身执行的操作则不会。foo = ...
ref
out
0赞
Harper Shelby
10/22/2010
@Jon Skeet:好的,我省略了第三个选项。人们认为C++令人困惑!
0赞
Justin Niessner
10/22/2010
#2
如果希望能够访问原始值,请使用第二种方法。
如果你不关心原始值,你可以使用任何一个(不过我可能仍然会使用第二个)。
无论哪种方式,在这种情况下,您都不会损害其他人的值(即使您重新分配值,它也不会将其返回给调用者)。
25赞
Jon Skeet
10/22/2010
#3
对参数值的更改对调用方不可见,除非它是 or 参数。ref
out
如果对参数引用的引用类型对象进行更改,则情况并非如此。例如:
public void Foo(StringBuilder b)
{
// Changes the value of the parameter (b) - not seen by caller
b = new StringBuilder();
}
public void Bar(StringBuilder b)
{
// Changes the contents of the StringBuilder referred to by b's value -
// this will be seen by the caller
b.Append("Hello");
}
最后,如果参数通过引用传递,则会看到更改:
public void Baz(ref StringBuilder b)
{
// This change *will* be seen
b = new StringBuilder();
}
有关更多信息,请参阅我关于参数传递的文章。
下一个:我可以修改传递的方法参数吗
评论