【问题标题】:What is the difference between a struct constructor with `this()` at the end and another without?最后带有`this()`的结构构造函数和没有的结构构造函数有什么区别?
【发布时间】:2019-04-11 17:17:49
【问题描述】:

假设我们有这两个结构......

public struct Example
{
    public int Number { get; set; }

    public Example(int Number)
    {
        Number = number;
    }
}

和:

public struct Example
{
    public int Number { get; set; }

    public Example(int number) : this()
    {
        Number = number;
    }
}

你可以看到有一个结构体,其构造函数末尾带有**this()**,而另一个没有。

两者有什么区别?

【问题讨论】:

标签: c# struct constructor


【解决方案1】:

调用 this() 将所有字段初始化为零。 C# 编译器要求在构造函数中初始化所有结构字段。因此,如果您不想指定所有字段,则应调用 this()。

不会编译:

struct A
{
    public int field1;
    public string field2;

     public A(string str)
     {
         field2 = str;
     }
}

给予:

错误 CS0171 字段“A.field1”必须在控制权返回给调用者之前完全分配...

没问题:

struct A
{
    public int field1;
    public string field2;

    public A(string str) : this()
    {
        field2 = str;
    }
}

很奇怪,但还可以:

struct A
{
    public int field1;
    public string field2;

    public A(string str)
    {
        this = new A(); // in structs 'this' is assignable
        field2 = str;
    }
}

struct A
{
    public int field1;
    public string field2;

    public A(string str)
    {
        this = default(A); // in structs 'this' is assignable
        field2 = str;
    }
}

【讨论】:

    【解决方案2】:

    更新

    对于一个班级

    不同之处在于调用this()的构造函数也会调用类的不带参数的构造函数。因此,例如,如果这是您的班级:

    public class Example
    {
        public int Number { get; set; }
    
        public Example(int number) : this()
        {
            Number = number;
        }
        public Example()
        {
            Console.WriteLine("Hello");
        }
    }
    

    然后包含this() 也会打印“Hello”。这是一种可以将构造函数链接在一起的方式,以便代码重用。

    对于结构

    您不能在结构中添加空构造函数,因此添加 this() 不会带来任何好处。感谢 vendettamit 唤醒了我疲惫的大脑。

    【讨论】:

    • CS0568 结构不能包含显式的无参数构造函数。
    • 取决于 C# 的版本,在 C# 5.0 中可以定义无参数的 struct 构造函数。
    【解决方案3】:

    在您的示例中,没有行为变化,因为this() 为未定义的结构调用无参数构造函数。

    请注意,在 C# 6.0 和更高版本中,您不能 re-define 结构的无参数构造函数,所以如果您这样做:

    public struct Example
    {
        public Example() // compile error in c# 6.0 and up
        {
        }
    }
    

    你会得到一个编译错误。更多详情here.

    在旧版本的 C# 中,您可以重新定义无参数构造函数,这意味着您可以通过修改无参数构造函数在参数化构造函数中注入额外的行为。

    除此之外,由于为 this() 构造函数生成的额外 IL 代码,可能会影响理论上的性能:

    Example..ctor:
    IL_0000:  ldarg.0     
    IL_0001:  initobj     UserQuery.Example
    IL_0007:  nop         
    IL_0008:  ldarg.0     
    IL_0009:  ldarg.1     
    IL_000A:  call        UserQuery+Example.set_Number
    IL_000F:  nop         
    IL_0010:  ret 
    

    【讨论】:

      【解决方案4】:

      没有区别。 this() 将调用无参数构造函数,这是定义结构所必需的,除非您重新定义它并自定义其行为,否则它不会做任何事情。如果是structs,则不允许定义自己的无参数构造函数; classes 你可以。

      但是,请注意,构造函数链接是在复杂构造场景中进行 DRY 的便捷工具:即当对象公开具有不同参数的大量构造函数时。

      【讨论】:

      • “结构定义”是什么意思
      • C#中有structs和classes,详见文档。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-10-23
      • 2014-06-11
      • 2016-06-30
      • 2019-08-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多