可选参数“必须是编译时常量”

时间:2022-09-28 11:34:57

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.

但编译器一直说sortExpression“必须是编译时常量”。对我来说,这似乎是一个完美的编译时常量,所以我不明白问题出在哪里。

8 个解决方案

#1


44  

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.

不,表达式PersonRespository.ColumnID未被归类为编译时常量。表达式“ID”是,但这不是您使用的默认参数。

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.

特别是,如果ColumnID是“只是一个普通字段”,那么对它的任何引用都将被解析为一个字段 - 所以如果你编译一个引用该字段的程序集,那么更改该值并重建包含PersonRepository的程序集,引用程序集会看到这种变化。

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.

有关什么算作常量表达式的更多详细信息,请参阅C#4语言规范的第7.19节。

#2


5  

You must declare your ColumnID as const.

您必须将ColumnID声明为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).

在代码中首次访问类时,将实例化静态只读字符串,并且还可以使用静态方法的返回值对其进行初始化,因此它不是编译器的编译时常量(即使在这种情况下它也是如此)显然是一个人阅读代码)。

#3


4  

const is something declared with const keyword.

const是用const关键字声明的东西。

readonly field can be assigned in constructor and its not compile time constant. the code that you've written right now runs in initializer (before constructor). const fields are 'baked' in as constants.

readonly字段可以在构造函数中分配,而不是编译时间常量。您现在编写的代码在初始化程序中运行(在构造函数之前)。 const字段作为常量'烘焙'。

#4


3  

change

更改

public static readonly string ColumnID = "ID";

to

public const string ColumnID = "ID";

#5


3  

readonly

只读

The value of a readonly field can be changed (in a constructor). You need a const.

可以更改readonly字段的值(在构造函数中)。你需要一个const。

#6


3  

Just for completeness, here are the three valid default values for an optional argument: ( from: MSDN: Named and Optional Arguments)

为了完整起见,以下是可选参数的三个有效默认值:(来自:MSDN:Named和Optional Arguments)

  1. a constant expression
  2. 一个恒定的表达
  3. an expression of the form new ValType(), where ValType is a value type, such as an enum or a struct; (note: only the parameterless constructor can be used)
  4. 表达式为新的ValType(),其中ValType是值类型,例如枚举或结构; (注意:只能使用无参数构造函数)
  5. an expression of the form default(ValType), where ValType is a value type.
  6. 形式为default(ValType)的表达式,其中ValType是值类型。

#7


2  

public const string ColumnID = "ID";

#8


2  

Try to change this

试着改变这个

public static readonly string ColumnID = "ID";

to

public const string ColumnID = "ID";

#1


44  

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.

不,表达式PersonRespository.ColumnID未被归类为编译时常量。表达式“ID”是,但这不是您使用的默认参数。

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.

特别是,如果ColumnID是“只是一个普通字段”,那么对它的任何引用都将被解析为一个字段 - 所以如果你编译一个引用该字段的程序集,那么更改该值并重建包含PersonRepository的程序集,引用程序集会看到这种变化。

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.

有关什么算作常量表达式的更多详细信息,请参阅C#4语言规范的第7.19节。

#2


5  

You must declare your ColumnID as const.

您必须将ColumnID声明为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).

在代码中首次访问类时,将实例化静态只读字符串,并且还可以使用静态方法的返回值对其进行初始化,因此它不是编译器的编译时常量(即使在这种情况下它也是如此)显然是一个人阅读代码)。

#3


4  

const is something declared with const keyword.

const是用const关键字声明的东西。

readonly field can be assigned in constructor and its not compile time constant. the code that you've written right now runs in initializer (before constructor). const fields are 'baked' in as constants.

readonly字段可以在构造函数中分配,而不是编译时间常量。您现在编写的代码在初始化程序中运行(在构造函数之前)。 const字段作为常量'烘焙'。

#4


3  

change

更改

public static readonly string ColumnID = "ID";

to

public const string ColumnID = "ID";

#5


3  

readonly

只读

The value of a readonly field can be changed (in a constructor). You need a const.

可以更改readonly字段的值(在构造函数中)。你需要一个const。

#6


3  

Just for completeness, here are the three valid default values for an optional argument: ( from: MSDN: Named and Optional Arguments)

为了完整起见,以下是可选参数的三个有效默认值:(来自:MSDN:Named和Optional Arguments)

  1. a constant expression
  2. 一个恒定的表达
  3. an expression of the form new ValType(), where ValType is a value type, such as an enum or a struct; (note: only the parameterless constructor can be used)
  4. 表达式为新的ValType(),其中ValType是值类型,例如枚举或结构; (注意:只能使用无参数构造函数)
  5. an expression of the form default(ValType), where ValType is a value type.
  6. 形式为default(ValType)的表达式,其中ValType是值类型。

#7


2  

public const string ColumnID = "ID";

#8


2  

Try to change this

试着改变这个

public static readonly string ColumnID = "ID";

to

public const string ColumnID = "ID";