C#中如何修改并返回函数内uint?类型参数的值
问题
我有一段C#代码,希望在函数内修改uint?类型的变量gid并返回新值(如9999),但新值未生效,调用函数时传入的原变量值也未改变。尝试使用ref关键字按引用传递也无效。
对比修改Unix Shell的代码段:
public string GenerateShell(DirectoryEntry de, string shell, int option) { shell = "/bin/test"; return shell; }
当参数为string类型时,修改shell为/bin/test后,原调用的变量值会被改变,但uint?类型却不行。相关代码如下:
public uint? GeneratePrimaryGid(DirectoryEntry de, uint? gid, int option) { gid = 9999; return gid; }
请问如何强制修改该uint?类型变量的值?
解答
首先纠正一个关键误解:你认为string参数修改后原变量会变化是错误的。string是不可变引用类型,在GenerateShell方法里给shell赋值新字符串,只是改变了方法内部局部变量的引用指向,原调用方的变量根本不会被修改——你觉得它变了,大概率是混淆了返回值的接收和参数传递的效果。
回到uint?的问题:uint?是值类型uint的可空包装,默认按值传递,方法内修改的是原变量的局部副本,自然不会影响外部的原变量。要直接修改原变量,正确使用ref关键字即可,你说用ref无效,肯定是调用时没加ref关键字,这是使用ref的必要步骤。
正确实现方式
- 方法定义时添加
ref:
public uint? GeneratePrimaryGid(DirectoryEntry de, ref uint? gid, int option) { gid = 9999; return gid; }
- 调用时必须带上
ref:
// 定义外部变量 uint? myGid = null; // 调用时加ref GeneratePrimaryGid(de, ref myGid, 1); // 此时myGid的值已经是9999
如果不想用ref,也可以通过接收方法的返回值来更新原变量:
uint? myGid = null; // 把返回值赋值给原变量 myGid = GeneratePrimaryGid(de, myGid, 1);
再澄清string的误区
你的GenerateShell方法,实际调用后原变量不会变化,比如:
string myShell = "/bin/bash"; GenerateShell(de, myShell, 1); // myShell还是"/bin/bash",没有任何变化 // 要更新必须接收返回值 myShell = GenerateShell(de, myShell, 1);
string的不可变性导致你无法通过参数传递修改原变量,只能通过返回值重新赋值,这和值类型的行为本质上是一致的。
内容的提问来源于stack exchange,提问作者Lance
相关产品推荐
相关产品推荐

