【问题标题】:Do auto implemented properties use private constructors for their initialization自动实现的属性是否使用私有构造函数进行初始化
【发布时间】:2018-10-23 06:47:58
【问题描述】:

我正在深入阅读 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# 中的作用,但如果它来自上面的文本,我无法理解它与自动实现的属性有何关系。

【问题讨论】:

  • 重点是,无论如何都应该调用构造函数。如果你真的想使用对象初始化语法,你实际上可以用这种无意义的语法创建一个新产品 new Product("West Side Story", 9.99m) { Name="West Side Story", Price = 9.99m } 如果你删除了两个构造函数,那么编译器会为你构建一个空的,但是如果你删除显式声明的一个,那么示例代码将失败,因为唯一可用的构造函数需要两个参数。

标签: c# automatic-properties private-constructor


【解决方案1】:

不要在类中使用私有字段,然后在属性中使用,而是按原样返回私有字段:

private int age;

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

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

自动实现属性的语法:

public int age {get; set;}

【讨论】:

  • 减号,因为这不能回答 OP 关于无参数构造函数及其与属性的关系的问题。
【解决方案2】:

这段代码在GetSampleProducts静态方法中使用了object initializer syntax。 对象初始化器只能用于具有无参数构造函数的类型,因为它都是关于语法糖的。 这个

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();调用需要无参数构造函数。并且会在设置属性之前为每个项目实际调用。

构造函数是私有的,但只要GetSampleProductsProduct类型内部,它就可以访问Product私有成员。如果你在这个类之外尝试相同的语法,它会失败。

所以,这个

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

其实这里的意思是构造函数不用于自动实现的属性,它是基于属性的初始化所必需的(这个术语是指对象初始化器),如果你去掉它,你会得到编译错误。

【讨论】:

    猜你喜欢
    • 2020-06-12
    • 2023-04-02
    • 2016-08-17
    • 2011-09-10
    • 1970-01-01
    • 1970-01-01
    • 2017-06-13
    • 2016-11-28
    • 1970-01-01
    相关资源
    最近更新 更多