Lia*_*ath 1 c# function value-type reference-type
我刚写了一个函数,我不明白为什么我得到的结果是:
private void ReplaceIfEmpty(string originalValue, string newValue)
{
if (string.IsNullOrWhitespace(originalValue))
{
originalValue= newValue;
}
}
Run Code Online (Sandbox Code Playgroud)
当我调用此函数时,原始值不会更新.我的理解是字符串是一个类,因此它是一个引用类型,因此我传入的值应该更新.你能解释一下为什么不是吗?
Jon*_*eet 19
这与参考类型和值类型无关.
您正在更改参数的值:
originalValue= newValue;
Run Code Online (Sandbox Code Playgroud)
对于没有refor或out修饰符的"普通"参数,该更改将永远不可见.
有关更多信息,请参阅我关于参数传递的文章,以及有关引用类型和值类型的文章,以确保您了解为什么有时它"看起来"像默认情况下通过引用传递引用类型.(它们不是:默认情况下所有参数都是按值传递的,只是对于引用类型,参数值是引用,而不是对象,因此对对象的更改仍然可以从调用者看到.)
所以你可以创建originalValue一个ref参数 - 但最好让方法返回一个参数string.我一般不愿意使用ref参数; 没有它们,代码通常更容易理解.
您传递了对字符串的引用.您没有传递对变量的引用.如果要更改变量,则执行以下操作:
private void ReplaceIfEmpty(ref string originalValue, string newValue) ...
Run Code Online (Sandbox Code Playgroud)
差异往往让人困惑.这样想吧.想象两个房子,而不是想象一个字符串.现在想象两张纸上有那些房子的地址; 那些是对房屋的引用.现在想象四个抽屉,每个抽屉都包含一张纸.抽屉标有p,q,x和y:
void M(House x, House y)
{
x = y;
}
...
House p = new House("123 Sesame Street");
House q = new House("1600 Pennsylvania Avenue");
M(p, q);
Run Code Online (Sandbox Code Playgroud)
这个程序做什么用的?你在抽屉里放了一张纸说"123芝麻街".你在抽屉里放了一张纸说"宾夕法尼亚大道1600号".
您在抽屉p中复印纸张并将副本放入抽屉x中.您在抽屉q中制作纸张的复印件并将副本放入抽屉y中.然后你打电话给M.M制作了抽屉里的东西的复印件,并把它放在抽屉里. 抽屉p不受影响.
现在考虑这种情况:
void M(ref House r, House s)
{
r = s;
}
...
House p = new House("123 Sesame Street");
House q = new House("1600 Pennsylvania Avenue");
M(ref p, q);
Run Code Online (Sandbox Code Playgroud)
这个程序做什么用的?你在抽屉里放了一张纸说"123芝麻街".你在抽屉里放了一张纸说"宾夕法尼亚大道1600号".
你在抽屉p上写了一个粘滞便笺,上面写着"这个抽屉也称为r".
您在抽屉q中复印纸张并将副本放入抽屉中.
然后你打电话给M.M制作了抽屉里的东西的复印件并把它放在抽屉里,这与抽屉p相同.
合理?
您没有更改作为参数传递的变量的值originalValue,您正在尝试为其分配新实例,对于引用意味着该变量指向新引用 - 更新您需要传递字符串的引用 ref - 默认情况下引用是按值传递的,因此您传递的变量永远不会更新:
private void ReplaceIfEmpty(ref string originalValue, string newValue)
{
if (string.IsNullOrWhitespace(originalValue))
{
originalValue = newValue;
}
}
Run Code Online (Sandbox Code Playgroud)
一个更好的方法是返回新的字符串:
private string ReplaceIfEmpty(string originalValue, string newValue)
{
if (string.IsNullOrWhitespace(originalValue))
return newValue;
else
return originalValue;
}
Run Code Online (Sandbox Code Playgroud)
或者更方便使它成为一种扩展方法:
public static string ReplaceIfEmpty(this string originalValue,
string replaceValue)
{
if (string.IsNullOrWhitespace(originalValue))
return replaceValue;
else
return originalValue;
}
Run Code Online (Sandbox Code Playgroud)