在C#中,如果没有定义默认值,为什么要调用:this()构造函数?

时间:2017-12-02 14:30:25

标签: c#

:this()C# documentation

中为此示例提供了什么目的
public struct Dog
{
   public string Breed { get; set; }

   public Dog(string breedName) : this()
   {
      Breed = breedName;
   }
}

2 个答案:

答案 0 :(得分:2)

本质上,当存在参数化构造函数时,C#编译器如何以不同方式处理引用类型和值类型。

对于引用类型,如果程序员已经定义了参数化构造函数,那么编译器将发出默认的无参数构造函数,但是对于Value类型,它仍然在您的情况下。 struct是一种值类型。

即使我删除了对默认构造函数的调用,然后下面的代码也能正常工作,因为编译器正在发出Program类正在使用的默认无参数构造函数:

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var breed = new Dog();
        }
    }


    public struct Dog
    {
        public string Breed { get; set; }

        public Dog(string breedName) //: this()
        {
            Breed = breedName;
        }
    }
}

当你这样做时有效:

public Dog(string breedName) : this()
{
    Breed = breedName;
}

在参数化构造函数启动之前,您实际上正在调用默认构造函数(对我们来说是不可见的)。

在同一行上,引用类型的工作方式不同:

namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var objMyClass = MyClass(); //gives error as compiler isn't emitting any default constructor
        }
    }

    public class MyClass
    {
        public MyClass(int i)
        {

        }
    }
}

答案 1 :(得分:2)

如果没有: this(),代码将无法使用.NET Framework提供的C#编译器进行编译,因为您可能会在初始化之前观察到struct字段:

Compiler error message

请记住,您正在调用属性设置器,它可以执行其他实例方法也可以执行的操作。

public struct Foo
{
   public int bar;
   public int Baz {
     get { return 0; }
     set { Console.WriteLine(bar); }
   }

   public Foo(int value)
   {
      Baz = 0;
   }
}

这必须无效,因为它会访问未初始化的bar。为了使其无效,C#编译器不允许结构构造函数调用任何实例方法,包括属性设置器,直到为所有字段分配了值。链接: this()是确保初始化所有字段的简单方法。

Roslyn编译器在C#6中略微放宽了这条规则。