初始化属性和构造方法初始化属性的执行顺序

什么是初始化属性

在声明属性的同时直接给属性进行初始化。

public IEnumerable<Score> MyScores { get; set; } = new HashSet<Score>();

若当一个类的属性是引用类型时,我们必须要先初始化该引用类型,才可以操作该类型。
比如:

public class User
{

    public int Id { get; set; }

    public ICollection<Score> Scores { get; set; }
}

public class Score
{
    public int Mark { get; set; }
}

我有了两个类型,其中,User 类中有一个 Scores 属性是类 Score 导航属性。

当我们需要使用到 Scores 属性时,你可以有以下几种方式:
1、显示地手动实例化:

var user = new User();
user.Scores = new List<Score>(); //手动的 new 一次
user.Scores.Add(new Score { Mark = 100 });

当然,这样很麻烦,因为每一次都需要自己去实例化,保不齐忘记了就抛异常了。

2、在构造方法里实例化:

public User()
{
    this.Scores = new HashSet<Score>();
}

因此,当我 new User() 时,就会执行构造方法,因此 Scores 也会跟着实例化了,所以我不用担心使用的时候有没有被实例化。这种方法应该被经常推荐使用

3、直接初始化属性

public ICollection<Score> Scores { get; set; } = new HashSet<Score>();

如果这样使用,就不需要在构造方法里再去实例化了,当然更方便。

那初始化属性和构造方法实例化的区别是什么?

既然构造方法里都能实例化了,那为什么还弄一个初始化属性呢?

这就需要去了解他们的执行顺序了。用简单的 debugger 来直观的表示。

public class User
{
    public User()
    {
        this.Scores = new HashSet<Score>();
    }

    public int Id { get; set; }

    public ICollection<Score> Scores { get; set; }

    public IEnumerable<Score> MyScores { get; set; } = new HashSet<Score>();
}

改造一下这个 User 类,声明了两个属性都是 Score 类型的导航属性,一个用了构造方法去实例化,一个使用初始化属性来实例化。

然后我们开始调试:
在这里插入图片描述
首先进入了断点,因为还没有实例化 User , 所以 user 对象是 null

然后按了 F11,进入逐步调试
在这里插入图片描述
你会惊奇地发现,程序先走了初始化属性这一步;

在这里插入图片描述
这个时候,才开始进入构造方法里,但是这时,初始化属性的 MyScores 对象已经可以被使用了,但由于构造方法还没有执行,因此 Scores 对象还是 null

在这里插入图片描述
当构造方法执行完毕,Scores 对象也被实例化。

因此我们得出了一个结论:初始化属性优先于构造方法

这都是一瞬间的事情,基本上没什么区别吧?

想一个场景,如果你需要在构造方法里做逻辑判断的时候,你就很有用了。

public User()
{
   if (MyScores == null)
   {
       this.Scores = new HashSet<Score>();
   }
}

当然,了解了执行顺序,就看你需要在什么样的场景去做使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

叫我 Teacher 周

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值