Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optional parameters "must be a compile-time constant"

Tags:

c#

.net

I have a class divided in two partial files, like this:

public partial class PersonRepository : BaseRepository<Person> {     public static readonly string ColumnID = "ID";     ... 

and

public partial class PersonRepository : BaseRepository<Person> {     public List<Person> GetByCompany(int companyID, string sortExpression = ColumnID)     {     ... 

But the compiler keeps saying that sortExpression "must be a compile-time constant". To me it seems a perfect compile-time constant, so I don't understand where the problem is.

like image 895
Alessandro Avatar asked Oct 06 '11 08:10

Alessandro


People also ask

Are optional parameters bad practice?

The thing with optional parameters is, they are BAD because they are unintuitive - meaning they do NOT behave the way you would expect it. Here's why: They break ABI compatibility ! so you can change the default-arguments at one place.

What is compile-time constant in C?

A compile-time constant is a value that can be (and is) computed at compile-time. A runtime constant is a value that is computed only while the program is running. If you run the same program more than once: A compile-time constant will have the same value each time the application is run.

What is default or optional parameter?

A parameter with a default value, is often known as an "optional parameter". From the example above, country is an optional parameter and "Norway" is the default value.


2 Answers

No, the expression PersonRespository.ColumnID is not classified as a compile-time constant. The expression "ID" is, but that's not what you're using as the default parameter.

In particular, if ColumnID is "just a normal field" then any references to it will be resolved as a field - so if you compile an assembly which refers to the field, then change the value and rebuild the assembly containing PersonRepository, the referring assembly will see that change.

If you change your declaration to:

 public const string ColumnID = "ID"; 

then it is a compile-time constant expression. That means in our previous scenario, the value of the constant is baked into any code that refers to it - and changing the value later without recompiling that referring code won't change the value used by that referring code.

See section 7.19 of the C# 4 language specification for more details about what counts as a constant expression.

like image 123
Jon Skeet Avatar answered Oct 09 '22 22:10

Jon Skeet


You must declare your ColumnID as const.

The static readonly string will be instantiated when the class is first accessed in your code, and you could also initialize it with the return value of a static method, so it's not a compile-time constant for the compiler (even if in this case it obviously is for a person reading the code).

like image 26
Paolo Tedesco Avatar answered Oct 09 '22 21:10

Paolo Tedesco