【问题标题】:Const function parameter in C# [duplicate]C#中的const函数参数[重复]
【发布时间】:2012-06-14 11:07:17
【问题描述】:

可能重复:
Read-only (“const”-like) function parameters of C#
Why is there no const member method in C# and const parameter?

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

如果我没记错的话,下面的意思是,该方法不能改变引用并且引用本身是一个常量引用。

C++ 示例

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

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

我问的原因是,我试图通过引用传递一个对象(为了速度),同时不希望任何人改变它。

【问题讨论】:

  • 我发誓我看到另一个用户在不到 12 小时前提出了相同/类似的问题......
  • 您应该永远在 C# 中出于性能原因通过引用传递,它不起作用。无论如何,大多数对象都是引用,通过引用传递它们没有优势,也有一些劣势。
  • @KonradRudolph:通过引用传递引用类型的参数确实有时会有优势。我不经常使用ref,但偶尔它肯定是有意义的。
  • @KonradRudolph:为什么它不起作用?在传递结构时,它当然应该提供性能优势。

标签: c#


【解决方案1】:

2020 年 9 月 16 日更新

现在似乎有 in parameter modifier 表现出这种行为(本质上是 ref readonly)。简要搜索一下您何时会使用它会得出以下答案:

Why would one ever use the "in" parameter modifier in C#?

原始答案

C# 没有等价物,它已经被问过manymanymanymany 次。

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

如果您的意思是要阻止方法更改引用,那么默认情况下,如果您“通过引用”传递它,您实际上是通过值传递引用。方法中更改引用指向的任何尝试只会影响本地方法副本,而不是调用者的副本。这可以通过在引用类型上使用 ref 关键字来更改,此时方法可以将引用指向新的底层对象,并且它影响调用者.

【讨论】:

  • 在 C# 中现在是新的,您可以使用 in 关键字将值类型作为常量传递
  • @divyang4481 我快速浏览了文档,但没有看到任何示例说明您的意思,您可以发布一些内容吗?
  • 无法相信建议 ref 允许更改值的答案被接受并且具有最高数量的出价如此快速地添加来自官方 C# 文档的报价:- in - 指定此参数通过引用传递,但仅由被调用的方法读取。 - ref - 指定这个参数是通过引用传递的,并且可以被调用的方法读取或写入。 -out - 指定这个参数是通过引用传递的,由被调用的方法写入。
【解决方案2】:

对于值类型(intdoublebytechar、...、struct),参数以值的形式出现,因此保证不会影响调用模块。

对于string类型,虽然它是一个引用类型,但它在CLR中是不可变的,所以你在过程中所做的任何事情都不会影响原始字符串。

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

【讨论】:

  • String 不是“在 CLR 中是不可变的”(不管这意味着什么),而只是在其接口上。但是StringBuilder 类可以修改底层String 就好了(是的,它确实修改了System.String 实例!)。
  • @KonradRudolph:谢谢。我只是按照 MSDN 所说的去做。 msdn.microsoft.com/en-us/library/362314fe.aspx 明明说内容创建后不能更改。
  • @ja72 措辞上的差异相当显着。字符串不能通过其公共接口修改,这意味着您永远无法修改字符串。但是,在内部,字符串可以被修改,事实上它们是可以修改的,但它们只是以这样一种方式修改,即用户(即您)永远不会看到修改。如果您不使用 CLR 一词,而是使用 BCL,那么您的陈述将是正确的。
  • @KonradRudolph 虽然StringBuilder 确实使用FastAllocateString() 内部调用来memcpy 为一个新的固定大小的String (@987654322) 初始内存内容@,它只是为了初始构造而这样做,这似乎不太符合“修改[ing] [an]底层String就好......”的精神。事实上我认为如果字符串的内容在其所谓的 GC“同步块”的惰性初始化之后 被修改,那么这里存在真正的危险,因为它具有哈希码值的缓存。
  • @GlennSlayden 我并不是说客户端代码可以随意修改 System.String,只是它的不变性不是 CLR 属性;我相信你会同意这种情况没有特殊处理。您链接到的代码行与紧随其后的代码行不相关,后者通过指向其内容的固定指针对分配的字符串进行实际修改。
猜你喜欢
  • 1970-01-01
  • 2012-08-03
  • 2010-09-14
  • 2013-04-06
  • 2021-05-23
  • 2022-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多