为什么C#中的常量字段不能是非内置结构类型?

joh*_*ohv 5 c# struct const

class T
{
    enum E { }
    struct S { }
    interface I { }
    delegate void D();
    class C { }

    const E e = new E();
    //const S s = default(S); // ERROR
    const I i = default(I);
    const D d = default(D);
    const C c = default(C);

    const int x = 10;
    const string y = "s";

    private void MyMethod(
        E e = new E(),
        S s = default(S), // NO ERROR
        I i = default(I),
        D d = default(D),
        C c = default(C),
        int x = 10,
        string y = "s")
    { }
}
Run Code Online (Sandbox Code Playgroud)

除了常数struct类型的字段外,所有上述都是可能的.

我可以看到为什么非string引用类型将默认为它们可以表示的唯一文字表达式null- 但如果我没有弄错,结构的默认值是结构的一个实例,其所有字段都设置为其默认值,基本上memset(0).此外,对于方法的默认参数,MyMethod编译器没有抱怨.那么,为什么一个const struct领域不可能呢?

有没有理由或仅仅是C#的编写方式?哦顺便说一下,允许枚举类型有默认构造函数的想法是什么?

(最初在这里找到的问题,它没有得到真正的答案.)

Mar*_*ell 5

从根本上说,真正的常量字段需要在IL中直接表示为元数据,这意味着:限制为一组直接在IL工作的已知类型.您可以说,您可以通过构造函数调用表达"常量",并在使用常量时替换该构造函数调用等,但是:

  1. 这将模拟非常接近的东西static readonly,已经存在并且可以使用
  2. 它不会被证明是恒定的 - 因为你的自定义类型可以在内部做任何事情

基本上,只需static readonly在您的情况下使用:

static readonly S s = default(S);
Run Code Online (Sandbox Code Playgroud)

在枚举的情况下:所有值类型都有默认构造函数(在C#术语中)并且没有默认构造函数(以IL术语表示).薛定谔的构造者!所有半存在的默认构造函数意味着"将其初始化为零",并且它适用于任何值类型(它是initobjIL指令).实际上,在C#中,您还可以通过另外两种方式为枚举执行此操作:default(TheEnum)0- 因为文字0适用于任何枚举.