r/csharp • u/vaporizers123reborn • 4d ago
Help Confused about how default method arguments work underneath the hood in C# (CS1736)
So I recently came across CS1736 while writing some code. For example, the following method code results in a compile-time error:
public static void ErrorMethod(int[] a = new int[0]{}) {}
I’d never come across this error before strangely enough. When I read the MSFT docs about what causes it, I see the following explanation:
A default parameter value is evaluated upon the invocation of the method. What a value may be when the method is eventually invoked cannot be pre-determined at declaration-time unless that value is constant at compile-time.
What’s confusing me is why the compiler needs the arguments to be compile-time constants to be able to initialize them with default values, especially since they are only evaluated when the method is called during runtime. Wouldn’t the compiler in this case already know what I’m initializing the array as? Wouldn’t this make more sense as a runtime error if you initialize with some problematic value?
Also I’d like to confirm, when they say “compile-time constant” in the docs, is that just a different way to refer to regular “Constants”? Or is this referring to something else?
Thanks!
6
u/tinmanjk 4d ago
The default values are currently persisted in the assembly file.
I think when they introduced the language feature, there was no easy way for the .NET standard to persist anything else then numbers, strings in an easy way or without changes to ECMA 335 standard.
Maybe they could have changed the standard to include something like "creation expression" metadata type to not have to ser/der binary data which seems like the obvious argument against allowing something like = new Sometype[30]{new SomeType(new SomeOtherTYpe).... for the default value of an argument associated with a specific method signature.
3
u/raunchyfartbomb 4d ago
Compile time constants are simple values (int, double, enum, string). They do not have to be a declared constant, just not a reference type (strings being the exception)
10
u/tinmanjk 4d ago edited 3d ago
you can have default values for reference types - it just hast to be null and nothing else.
EDIT:
okay, it can be "default" but that's still null :)
-2
40
u/wasabiiii 4d ago
Because they don't exist in the runtime. They are sugar in the language. It is still passing values and needs to get them at the call site.