19

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

Having programmed in C++ in the past, I recall we could make a constant reference/pointer parameter in a method.

If my memory is correct, the below means, that the method cannot alter the reference and the reference itself is a constant reference.

C++ example

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

Is there an equivalent in C# for methods in a class?

The reason why I'm asking is, I'm trying to pass a object by reference (for speed) and at the same time don't want anyone to alter it.

Community
  • 1
  • 1
TheLazyChap
  • 1,852
  • 1
  • 19
  • 32
  • I swear I saw the same /similar question asked less than 12 hours ago by another user.... – Mitch Wheat Jun 11 '12 at 14:18
  • You should *never* pass by reference for performance reasons in C#, it doesn’t work. Most objects are references anyway, passing them by reference has no advantage, and some disadvantages. – Konrad Rudolph Jun 11 '12 at 14:18
  • 2
    Look here - http://stackoverflow.com/q/3826542/763026 – Angshuman Agarwal Jun 11 '12 at 14:19
  • 2
    @KonradRudolph: Passing a reference-type parameter by reference *does* have advantages on occasion. I don't *often* use `ref`, but it can definitely make sense occasionally. – Jon Skeet Jun 11 '12 at 14:20
  • 1
    @KonradRudolph: why wouldn't it work? It should certainly provide performance benefits when passing structs. – vgru Jun 11 '12 at 14:22
  • @Jon Obviously I meant in the general case (“for performance reasons”), not for the case which it has been purposed for. That said (since we’re already having the discussion), I oppose `out` parameters (and consequently also `ref` parameters) on principle. It’s bad design. Use the return value properly instead. .NET missed many opportunities of good design by providing wrong `TryParse` methods instead of shipping with a `Nullable` or `Option` type from the start. – Konrad Rudolph Jun 11 '12 at 14:22
  • http://stackoverflow.com/questions/3263001/why-const-parameters-are-not-allowed-in-c-sharp – S2S2 Jun 11 '12 at 14:24
  • @Groo Even for structures it’s *almost* always detrimental for performance, and .NET guidelines state that structures should not exceed a certain size (in order to be copied efficiently, since that’s the norm). There are some outliers but I they are exceptional enough to be more confusing when mentioned. An expert dealing with those will know what to do anyway. – Konrad Rudolph Jun 11 '12 at 14:25
  • @CSharpVJ I don’t often disagree with Eric but here he’s simply wrong. `const` *does* get used by the compiler as a type system hint for optimisations. Yes, you can break the `const` promise but you can do the same with .NET type hints (accessibility rules, for instance, or `readonly`), using reflection or unsafe code. – Konrad Rudolph Jun 11 '12 at 14:28
  • @KonradRudolph: I didn't think that was obvious at all, to be honest... – Jon Skeet Jun 11 '12 at 14:36
  • @KonradRudolph Well..Every feature functional or technical can be added/extended if C# can be made completely open source and for that matter fully extensible...That would wash away all the confusions/arguments/justifications/misunderstandings and would start a new revolution in the programming world...For this matter of extensible and open source fact I am just a lame programmer and a beginner (don't even know if this can be done) but if I had the responsibility on C# / .Net-I would immediately start taking actions on these open source and extensible facts and change the programming world. – S2S2 Jun 11 '12 at 15:06
  • @CSharpVJ That wasn’t my argument at all. What I remarked was that Eric’s description of the `const` semantics in C, and its consequent usefulness, were technically wrong. He claims that `const` is broken because it can be circumvented. In reality, `const` is no more broken than `private` or `readonly` in C#. – Konrad Rudolph Jun 11 '12 at 15:08
  • @KonradRudolph I know that wasn't the argument..in fact I was just making a suggestion to the programming world (in my just last comment) in the consequence of confusions and discussions posted here. – S2S2 Jun 11 '12 at 15:14

2 Answers2

25

Update 16/09/2020

There now appears to be the in parameter modifier that exhibits this behaviour (in essence, a ref readonly). A brief search on when you would ever use this yields the following answer:

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

Original Answer

There is no equivalent for C# and it has been asked many, many, many, many times before.

If you don't want anyone to alter the "reference", or perhaps you mean the content of the object, make sure the class doesn't expose any public setters or methods of mutating the class. If you cannot change the class, have it implement an interface that only publicly exposes the members in a read-only fashion and pass the interface reference instead.

If you mean you want to stop the method from changing the reference, then by default if you pass it "by reference", you are actually passing the reference by value. Any attempt from the method to change what the reference points to will only affect the local method copy, not the caller's copy. This can be changed by using the ref keyword on a reference type, at which point the method can point the reference at a new underlying object and it will affect the caller.

Adam Houldsworth
  • 63,413
  • 11
  • 150
  • 187
  • 2
    in C# now new you can use in keyword to pass value type as constant – divyang4481 Mar 20 '20 at 07:12
  • @divyang4481 I had a quick look at the docs and couldn't see any examples of what you mean, can you post something? – Adam Houldsworth Mar 20 '20 at 07:56
  • please refer this link https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/in-parameter-modifier – divyang4481 Mar 20 '20 at 08:28
  • Cannot believe that the answer that suggests ref which let change the value is accepted and has highest number of bids so quickly adding quotation from official C# documentation: - in - specifies that this parameter is passed by reference but is only read by the called method. - ref - specifies that this parameter is passed by reference and may be read or written by the called method. - out - specifies that this parameter is passed by reference and is written by the called method. – Sebastian Xawery Wiśniowiecki Sep 15 '20 at 22:57
1

For value types (int, double, byte, char,...,struct) the arguments come in as values and therefore are guaranteed not to affect that calling module.

For string type, although it is a reference type, it is immutable by the CLR, such that nothing you do inside the procedure can affect the original string.

For other reference types (class) there is no way to guarantee changes in the class from the method.

John Alexiou
  • 28,472
  • 11
  • 77
  • 133
  • 1
    String is *not* “immutable by the CLR” (whatever that means) but simply by its interface. But the `StringBuilder` class can modify the underlying `String` just fine (and yes, it does modify a `System.String` instance!). – Konrad Rudolph Jun 11 '12 at 14:36
  • 1
    @KonradRudolph: Thanks. I was just going by what MSDN says. http://msdn.microsoft.com/en-us/library/362314fe.aspx They clearly say the contents cannot be changed after it is created. – John Alexiou Jun 11 '12 at 14:45
  • @ja72 The difference in wording is rather significant. Strings cannot be modified through their public interface, meaning YOU can't ever modify a string. However, internally, strings can be modified, and in fact they are, but they are only modified in such a way that the modifications are never visible to users (i.e. you). Had you not used the word CLR, but rather, the BCL, your statement would have been correct. – Servy Jun 11 '12 at 15:04
  • @KonradRudolph While it's true that `StringBuilder` uses the `FastAllocateString()` internal call to *memcpy* the initial memory contents for a new `String` of a fixed size ([as shown here](https://referencesource.microsoft.com/#mscorlib/system/text/stringbuilder.cs,399), it does this only for initial construction, which seems less in the spirit of "*modify[ing] [an] underlying `String` just fine...*" willy-nilly. In fact I think there is a real hazard here if a string's contents get modified *after* the lazy init of its so-called GC "sync-block", since it has a cache of the hash code value. – Glenn Slayden Feb 13 '21 at 22:37
  • @GlennSlayden I’m not saying that client code can modify a `System.String` at will, merely that its immutability isn’t a CLR property; as I’m sure you’ll agree there’s no special treatment for this case. The line of code you’ve linked to isn’t as relevant as the lines that just follow it, which perform the actual modification of an allocated string in place, via a fixed pointer to its contents. – Konrad Rudolph Feb 14 '21 at 09:54
  • @KonradRudolph No, my point is that what makes the `StringBuilder` example ***less*** relevant is that it has no possibility for the string instance under mutation to ever have had any lifetime of public visibility. As such, the case *simply can't implicate* the far-ranging issues that make mutation such a richly interesting topic. Namely, concurrent consistency, which then implicates races, or the stale hash code issue I mentioned, etc. To coin a pun, for any given instance "mutability is moot" until it gets published. Mutability only matters "in the wild", with possible multi/public access. – Glenn Slayden Feb 14 '21 at 11:51
  • Why is this discussion happening now and here? – John Alexiou Feb 14 '21 at 16:23
  • I want const values not to keep references the same but to prevent someone from accidentally changing the value. I am using it as a way to pass delta time to objects and so I don't want a parent to accidentally modify the delta time for a child. – Dynamiquel Dec 28 '21 at 16:25