# 原型

struct ssss
{
    int x, y;
}
struct aaaa
{
    int x, y;
    public aaaa(int a)
    {
        x = a;
        y = 100;
    }
}
struct bbbb
{
    int x, y;
    public bbbb(int a)
    {
        this = new bbbb();
        y = 1;
    }
}

对应 IL 代码:

# ssss 类

.class private sequential ansi sealed beforefieldinit ssss
	extends [mscorlib]System.ValueType
{
	// Fields
	.field private int32 x
	.field private int32 y
} // end of class ssss

# aaaa 类

.class private sequential ansi sealed beforefieldinit aaaa
	extends [mscorlib]System.ValueType
{
	// Fields
	.field private int32 x
	.field private int32 y
	// Methods
	.method public hidebysig specialname rtspecialname 
		instance void .ctor (
			int32 a
		) cil managed 
	{
		// Method begins at RVA 0x211c
		// Header size: 1
		// Code size: 17 (0x11)
		.maxstack 8
		IL_0000: nop
		IL_0001: ldarg.0
		IL_0002: ldarg.1
		IL_0003: stfld int32 aaaa::x
		IL_0008: ldarg.0
		IL_0009: ldc.i4.s 100
		IL_000b: stfld int32 aaaa::y
		IL_0010: ret
	} // end of method aaaa::.ctor
} // end of class aaaa

# bbbb 类

.class private sequential ansi sealed beforefieldinit bbbb
	extends [mscorlib]System.ValueType
{
	// Fields
	.field private int32 x
	.field private int32 y
	// Methods
	.method public hidebysig specialname rtspecialname 
		instance void .ctor (
			int32 a
		) cil managed 
	{
		// Method begins at RVA 0x211c
		// Header size: 1
		// Code size: 16 (0x10)
		.maxstack 8
		IL_0000: nop
		IL_0001: ldarg.0
		IL_0002: initobj bbbb
		IL_0008: ldarg.0
		IL_0009: ldc.i4.1
		IL_000a: stfld int32 bbbb::y
		IL_000f: ret
	} // end of method bbbb::.ctor
} // end of class bbbb

# 调用

ssss s = new ssss();
bbbb b = new bbbb(123);
aaaa a = new aaaa(321);
IL_0010: ldloca.s 0
IL_0012: initobj ssss
IL_0018: ldloca.s 1
IL_001a: ldc.i4.s 123
IL_001c: call instance void bbbb::.ctor(int32)
IL_0021: ldloca.s 2
IL_0023: ldc.i4 321
IL_0028: call instance void aaaa::.ctor(int32)

# 总结

  • 无自定义带参数构造函数,结构体直接外部调用 initobj 初始化
  • 带自定义带参数构造函数,结构体自定义构造函数中可调用 new 操作符执行 initobj 初始化
  • 带自定义带参数构造函数,初始化赋值走正常赋值

initobj:将位于指定地址的值类型的每个字段初始化为空引用或适当的基元类型的 0

注:C# 10.0 才支持无参构造函数,因此之前的语法不支持内联初始化: