当前位置: 首页 > 知识库问答 >
问题:

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

马新觉
2023-03-14

我正在深入阅读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个答案

归鹤龄
2023-03-14

而不是在类中使用私有字段

private int age;

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

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

自动实现属性的语法:

public int age {get; set;}
蒋寒
2023-03-14

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

构造函数是私有的,但是只要< code>GetSampleProducts在< code>Product类型内部,它就可以访问< code>Product私有成员。如果您在该类之外尝试相同的语法,将会失败。

所以,这个

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

实际上意味着构造函数不用于此处的自动实现属性,它是基于属性的初始化所必需的(此术语表示对象初始值设定项),如果将其删除,则会收到编译错误。

 类似资料:
  • 我试图包装两个C++类:Cluster和ClusterTree。ClusterTree有一个方法get_current_cluster(),它实例化一个集群对象,并返回对它的引用。ClusterTree拥有集群对象,并在C++中管理其创建和删除。 我用cython包装了Cluster,生成了PyCluster。 PyCluster应该有两种创建方式: 1)通过传入两个数组,这意味着Python应该

  • 问题内容: 我在实例类型“ Person”中添加了一个实例变量,该类是引用类型(“ Date”,我为此编写了一个类)。因此,在我的Person类的构造函数中,我试图使用Date类的构造函数初始化Date属性,但是不确定如何执行此操作。以前,我只初始化过原始类型(或字符串),如下所示。这是我的代码中的一段。我不确定如何初始化“生日”,以便它使用Date类的构造函数。谢谢! 问题答案: 您是说要使用D

  • 假设你有这个代码片段 例如,如果编译器决定让它看起来像 这将是一个问题,因为calculateWaitTime()生成一个新线程,该线程可能会将集合视为null或其中没有1。 那么问题又来了,这种重新排序可能吗?或者所有在构造函数之外初始化的最终字段都是在构造函数之前初始化的,或者至少总是由编译器移动到构造函数的顶部

  • 考虑以下代码: 以下是一些引用的标准 拷贝初始化 从cppreference复制引用的初始化 如果object是lvalue表达式,其类型是T或从T派生的,且具有相等或较少CV限定性,则该引用绑定到由lvalue标识的对象或其基类子对象。 如果object是lvalue表达式,其类型隐式转换为T或从T派生的类型,具有相等或较少CV限定性,则考虑源类型及其基类返回lvalue引用的非显式转换函数,并

  • 我试图理解为什么在谈到构造函数时,类成员的可访问性之间存在差异。 考虑下面的例子: 的私有成员作为私有成员,不应从访问。对于字段和方法,情况确实如此,但构造函数似乎没有遵循相同的规则。 从JLS-8(6.6.1.确定可访问性)中,我们可以阅读: [...] 引用类型的成员(类、接口、字段或方法)或类类型的构造函数只有在类型可访问且声明该成员或构造函数允许访问时才可访问: > [……] 否则,成员或

  • 问题内容: 我有两个班,第一个是我的主班,第二个是我的编辑框架班。 我的第二个类(UpdateGUI)在其构造函数中提供oldName,并对其进行编辑,当我单击时,它将newName发送给我的第一个类。 我的第二堂课: 我的问题是,为什么newName为null? 更新: UpdateGUIDialog类: 输出: 我需要打印而不是null。 问题答案: Java对象有点像真实对象。并顾名思义:它