代码之家  ›  专栏  ›  技术社区  ›  thebenman

自动实现的属性是否使用私有构造函数进行初始化

  •  0
  • thebenman  · 技术社区  · 8 年前

    我在深入阅读Jon Skeet的C#时,偶然发现了中自动实现属性的解释 C#3 。

    其代码为:

    class Product
    {
        public string Name { get; private set; }
        public decimal Price { get; private set; }
    
        public Product(string name, decimal price)
        {
            Name = name;
            Price = price;
        }
    
        Product() {}
    
        public static List<Product> GetSampleProducts()
        {
            return new List<Product>
                   {
                       new Product { Name="West Side Story", Price = 9.99m },
                       new Product { Name="Assassins", Price=14.99m },
                       new Product { Name="Frogs", Price=13.99m },
                       new Product { Name="Sweeney Todd", Price=10.99m}
                   };
        }
    }
    

    解释这一点的文字是

    现在属性没有任何代码(或可见变量!)与它们关联,并且您正在以一种非常不同的方式构建硬编码列表。由于没有名称和价格变量可访问,您不得不在类中的任何地方使用属性,以提高一致性。 为了实现新的基于属性的初始化,您现在有了一个私有的无参数构造函数。(在设置属性之前,会为每个项调用此构造函数。) 在本例中,您可以完全删除公共构造函数,但没有外部代码可以创建其他产品实例。

    我不能把我的头绕在用粗体标记的部分上。它表示私有构造函数用于自动实现的属性,并且在每次设置之前都会被调用。然而,即使我在那里放了一个控制台,它也没有被调用。即使删除了私有构造函数,代码也运行良好。

    我知道C#中私有构造函数的作用,但如果它来自上面的文本,我无法理解它与自动实现属性的关系。

    2 回复  |  直到 8 年前
        1
  •  3
  •   UladzislaÅ­    8 年前

    这段代码正在使用 object initializer syntax 在里面 GetSampleProducts 静态方法。 对象初始值设定项只能用于具有无参数构造函数的类型,因为它都是关于语法糖的。 这

    var p = new Product { Name="West Side Story", Price = 9.99m }
    

    真的转化成了这件事

    var p = new Product();
    p.Name = "West Side Story";
    p.Price = 9.99m;
    

    这意味着 var p = new Product(); 呼叫在设置属性之前,实际上会为每个项目调用它。

    构造函数是私有的,但 GetSampleProducts 在里面 Product 类型,它可以访问 产品 私人成员。如果在这个类之外尝试相同的语法,它将失败。

    所以,这个

    为了实现新的基于属性的初始化,您现在有了一个私有的无参数构造函数。

    实际上,这意味着这里的构造函数不用于自动实现的属性,它是 基于属性的初始化 (这个术语的意思是对象初始值设定项),如果删除它,就会出现编译错误。

        2
  •  -2
  •   David Edel    8 年前

    而不是在类中使用私有字段;然后在property get中按原样返回私有字段:

    private int age;
    
    public int Age
    {get {return age;}
     set {age = value}
    }
    

    通过自动植入,可以在幕后创建私有int。

    自动实现属性的语法:

    public int age {get; set;}