Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么这不会创建默认构造函数?_C#_Constructor - Fatal编程技术网

C# 为什么这不会创建默认构造函数?

C# 为什么这不会创建默认构造函数?,c#,constructor,C#,Constructor,我想知道为什么会抛出异常(在执行时): 当我有一个带有默认参数的构造函数时(但我没有创建构造函数public foo(): 无参数构造函数不是在编译时生成的吗 不是编译时生成的无参数构造函数 默认的无参数构造函数仅在未定义构造函数时生成。如语言规范所示。这里有两个问题: 只有在您自己没有定义任何构造函数的情况下,才会自动为您生成无参数构造函数。显然,这里不是这种情况,因为您已经手动声明了构造函数 可选参数只不过是调用点的编译时语法糖。参数化构造函数不算无参数构造函数,即使其所有参数都是可选的 如

我想知道为什么会抛出异常(在执行时):

当我有一个带有默认参数的构造函数时(但我没有创建构造函数
public foo()

无参数构造函数不是在编译时生成的吗


不是编译时生成的无参数构造函数


默认的无参数构造函数仅在未定义构造函数时生成。如语言规范所示。

这里有两个问题:

  • 只有在您自己没有定义任何构造函数的情况下,才会自动为您生成无参数构造函数。显然,这里不是这种情况,因为您已经手动声明了构造函数

  • 可选参数只不过是调用点的编译时语法糖。参数化构造函数不算无参数构造函数,即使其所有参数都是可选的

  • 如果类不包含实例构造函数声明,则会自动提供默认实例构造函数

    因此,如果有构造函数,net将不会创建另一个无参数构造函数


    请参见。

    根据c#的语言规范:

    如果类不包含实例构造函数声明,则会自动提供默认实例构造函数。该默认构造函数仅调用直接基类的无参数构造函数。如果直接基类没有可访问的无参数实例构造函数,则会发生编译时错误

    由于您的类foo包含实例构造函数,因此不会生成默认构造函数。您需要声明自己的构造函数

    无参数构造函数不是在编译时生成的吗

    正如其他人所说,只有您自己没有提供接受参数的构造函数实现时,才会生成默认构造函数

    (§10.10.4)(重点):

    如果类不包含实例构造函数声明,则默认 实例构造函数是自动提供的 构造函数只调用直接函数的无参数构造函数 基类。如果直接基类没有可访问的 无参数实例构造函数,发生编译时错误

    如果查看IL中类型的签名,您将看到它创建了一个构造函数,其中包含两个参数,这些参数用
    [opt]
    标记进行注释,并具有默认值:

    .method public hidebysig specialname rtspecialname 
    instance void .ctor (
        [opt] int32 a,
        [opt] int32 b
    ) cil managed 
    {
        .param [1] = int32(0)
        .param [2] = int32(0)
        // Method begins at RVA 0x207c
        // Code size 9 (0x9)
        .maxstack 8
    
        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: nop
        IL_0007: nop
        IL_0008: ret
    } // end of method foo::.ctor
    

    这不是一个空构造函数,因为
    Activate.CreateInstance
    需要它。

    “不是编译时生成的无参数构造函数吗?”-除非您声明自己的构造函数。某些方法需要无参数构造函数,因此您可能需要有两个构造函数。添加:public foo(){}这里,第2点是关键。可选参数在调用方法时会转换为实际参数。这也意味着,如果具有默认参数的方法位于单独的程序集中,则您可以更改它们的值,然后仅更新该程序集,代码不会受到影响,因为调用方方法仍然具有其默认参数。
    public class foo : IAgentIndicator
    {
        public foo(int a = 0, int b = 0)
        {
        }
    }
    
    .method public hidebysig specialname rtspecialname 
    instance void .ctor (
        [opt] int32 a,
        [opt] int32 b
    ) cil managed 
    {
        .param [1] = int32(0)
        .param [2] = int32(0)
        // Method begins at RVA 0x207c
        // Code size 9 (0x9)
        .maxstack 8
    
        IL_0000: ldarg.0
        IL_0001: call instance void [mscorlib]System.Object::.ctor()
        IL_0006: nop
        IL_0007: nop
        IL_0008: ret
    } // end of method foo::.ctor