C#中的常量函数参数

20

可能是重复问题:
C# 中只读(类似于“const”)的函数参数
为什么 C# 中没有 const 成员方法和 const 参数?

过去我曾经使用过 C++ 进行编程,我记得我们可以在一个方法中创建一个常量引用/指针参数。

如果我的记忆正确,下面这个例子意味着该方法不能更改引用本身,而且引用本身是一个常量引用。

C++ 示例

void DisplayData(const string &value) const
{
   std::count << value << endl;
}

C#中是否有类似于类方法的等价物?

我提出这个问题的原因是,我想通过引用(为了速度)传递对象,同时又不希望任何人更改它。


我发誓我在不到12小时前看到另一个用户问了同样/类似的问题... - Mitch Wheat
在C#中,出于性能原因,您绝不能通过引用传递参数,这是行不通的。大多数对象本来就是引用,通过引用传递它们没有任何优势,反而会带来一些缺点。 - Konrad Rudolph
2
请看这里 - https://dev59.com/Cm865IYBdhLWcg3wat6l - Angshuman Agarwal
2
@KonradRudolph:有时候通过引用传递引用类型参数确实有优势。我并不经常使用 ref,但是在某些情况下它绝对是有意义的。 - Jon Skeet
1
@KonradRudolph:为什么不行呢?当传递结构体时,它肯定会提供性能优势。 - vgru
显示剩余8条评论
2个回答

25

更新于2020年9月16日

现在有一个in参数修饰符,它展示了这种行为(本质上是ref readonly)。对于何时使用此功能的简要搜索得出以下答案:

为什么C#中会使用“in”参数修饰符?

原始回答

C#没有类似的等效项,之前已经多次提出过许多许多许多许多次。

如果您不希望任何人更改“引用”,或者也许您指的是对象内容,请确保该类不公开任何可变异该类的公共设置器或方法。如果您不能更改该类,请让其实现一个接口,该接口仅以只读方式公开成员,并传递接口引用。

如果你想阻止这个方法改变引用,那么默认情况下,如果你传递的是“按引用传递”,实际上是通过值传递引用。方法尝试更改引用指向的内容时,只会影响本地方法副本,而不会影响调用者的副本。可以使用 ref 关键字来改变这种行为,此时该方法可以将引用指向一个新的基础对象,并且它将影响到调用者。


2
现在在C#中,您可以使用"in"关键字将值类型作为常量传递。 - divyang4481
@divyang4481 我快速查看了文档,没有找到您所说的示例,请您可以贴出一些吗? - Adam Houldsworth
请参考以下链接:https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/in-parameter-modifier - divyang4481
无法相信那个建议使用 ref 来改变值的答案被迅速接受并获得最高竞标数,这里加上一句来自官方 C# 文档的引用:
  • in - 指定该参数是按引用传递的,但只能由被调用方法读取。
  • ref - 指定该参数是按引用传递的,并且可以由被调用方法读取或写入。
  • out - 指定该参数是按引用传递的,并且由被调用方法写入。
- Sebastian Xawery Wiśniowiecki

1

对于值类型(intdoublebytechar、...、struct),参数作为值传递,因此保证不会影响调用模块。

对于string类型,虽然它是引用类型,但由于CLR的限制,过程内部所做的任何操作都不会影响原始字符串。

对于其他引用类型(class),无法保证方法中对类所做的更改。


1
字符串并非“由CLR不可变”(不管那是什么意思),而只是通过其接口不可变。但是StringBuilder类可以很好地修改底层的String(是的,它确实修改了一个System.String实例!)。 - Konrad Rudolph
1
@KonradRudolph:谢谢。我只是按照MSDN上的说法去做的。http://msdn.microsoft.com/en-us/library/362314fe.aspx 他们明确表示创建后内容不能更改。 - John Alexiou
@ja72措辞上的差别相当重要。字符串不能通过其公共接口进行修改,这意味着您永远无法修改字符串。但是,在内部,字符串可以被修改,实际上它们确实被修改了,但是它们只是以这样一种方式进行修改,即这些修改对用户(即您)永远不可见。如果您没有使用CLR这个词,而是使用BCL,那么您的说法就是正确的。 - Servy
@KonradRudolph 不,我的观点是StringBuilder示例的不太相关,因为在变异下的字符串实例从未公开可见过。因此,这种情况根本无法涉及使变异成为一个丰富有趣的主题的广泛问题。即并发一致性,然后涉及竞争或我提到的陈旧哈希代码问题等。用双关语来说,对于任何给定的实例,“可变性是无关紧要的”,直到它被发布。只有在“野外”中,可能存在多个/公共访问时,可变性才有意义。 - Glenn Slayden
我希望const值不仅保持引用不变,而且还能防止某人意外更改该值。我将其用作将增量时间传递给对象的一种方式,因此我不希望父级意外修改子级的增量时间。 - Dynamiquel
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接