c#中字段和set/get的执行顺序

本文关键字:get 执行 顺序 set 字段 | 更新日期: 2023-09-27 18:06:14

我对c#中关于字段设置和set/get属性的执行顺序感到困惑。为什么Test2中的值在构造函数调用时不设置,而在Test中的值是?

当创建一个类的实例时,是否有某种类型的隐藏/默认"构造函数"设置字段,但不调用属性的setter ?

setter是在构造函数之后自动调用还是必须显式调用?

最后,这个执行顺序是否有很好的理由?

输出:


测试:5Test2: 0

using System.IO;
using System;
class Program
{
    static void Main()
    {
        Test test = new Test();
        Test2 test2 = new Test2();
    }
}
class Test
{
    private int x = 5;
    public Test(){
        Console.WriteLine("Test: " + x);
    }
}
class Test2
{
    private int _x;
    private int x{
        get
        {
            return _x;
        }
        set
        {
            _x = 5;
        }
    }
    public Test2(){
        Console.WriteLine("Test2: " + x);
    }
}

c#中字段和set/get的执行顺序

当创建一个类的实例时,是否有某种类型的隐藏/默认"构造函数"设置字段,但不调用属性的setter ?

为什么要调用属性setter ?用来称呼它们是什么呢?(你的属性设置器不使用value,它通常会…)

这不是存在隐藏构造函数的问题——只是在调用基类构造函数之前执行字段初始化式。属性设置符被隐式调用而不是

来自c# 5规范第10.11.2节:

当一个实例构造函数没有构造函数初始化式,或者它有一个base(...)形式的构造函数初始化式时,该构造函数隐式地执行由在其类中声明的实例字段的变量初始化式指定的初始化。

注意,从c# 6开始,你也可以自动实现带有默认值的属性:

public int Foo { get; set; } = 10;

这只是意味着后备字段将初始化为10的值,就像普通字段一样。

您所需要做的就是初始化test2()中的后备字段,就像您在test()中定义字段一样。因此,您可能会有以下内容:

class Test2
{
private int _x = -1; // The default value is -1
private int x{
    get
    {
        return _x; // return whatever is in _x
    }
    set
    {
        _x = 5; // Change _x to 5 (or whatever is in value)
    }
}
public Test2(){
    Console.WriteLine("Test2: " + x); // should show -1
    Test2.x = 8;
    Console.WriteLine("Test2: " + x); // should show 8
}
}