Is the in parameter modifier really optional on the call site?

I'm a bit confused about the in parameter modifier: I know if I write in before a parameter it a read only reference, which is faster then passing big stuff by value. According to the documentation https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/in-parameter-modifier it says that the in parameter modifier is optional on the callsite:

Specifying in for arguments at the call site is typically optional. There is no semantic difference between passing arguments by value and passing them by reference using the in modifier. The in modifier at the call site is optional because you don't need to indicate that the argument's value might be changed. You explicitly add the in modifier at the call site to ensure the argument is passed by reference, not by value. Explicitly using in has the following two effects:

First, specifying in at the call site forces the compiler to select a method defined with a matching in parameter. Otherwise, when two methods differ only in the presence of in, the by value overload is a better match.

Second, specifying in declares your intent to pass an argument by reference

When I use it in my code:

public static kAssetKind? DetermineAssetKind(in string extension)...

And I call it here:

...{FilePath = mainFile, Kind = DetermineAssetKind(Path.GetExtension(mainFile)) ?? kAssetKind.Other};

it's okay the string is passed by reference, but if I write specifically in before:

DetermineAssetKind(in Path.GetExtension(mainFile))

then I get an error that it could be passed by reference. So there is a difference between an in on callsite and it says "Second, specifying in declares your intent to pass an argument by reference" but I thought it will pass it by reference even if I don't use in at the callsite? And does it even make sense to pass a string as in reference because classes are reference?

Upvotes: 0

Views: 171

Answers (1)

InBetween
InBetween

Reputation: 32780

I think you are misunderstanding the article.

The way I understand it is that considering the following method:

void Foo(in SomeBigValueType t)
{ ... }

The following two calls are the same:

SomeBigValueType v;
Foo(v);
Foo(in v);

Your issue seems to be unrelated to the article. in needs a storage location (aka variable). In your second example you aren’t passing one so you get an error; you’d get the same error with ref or out.

Upvotes: 1

Related Questions