【问题标题】:C# Auto-Implemented PropertiesC# 自动实现的属性
【发布时间】:2011-08-02 12:29:29
【问题描述】:

我对自动实现的属性相当陌生,而且大部分时间我发现它们非常简单,但在 Microsoft 网站中它指出:

在 C# 3.0 及更高版本中,当属性访问器中不需要额外的逻辑时,自动实现的属性使属性声明更加简洁。 它们还允许客户端代码创建对象。当您如下例所示声明属性时,编译器会创建一个私有的匿名支持字段,该字段只能通过属性的 get 和 set 访问器访问。

-- Auto-Implemented Properties (MSDN)

谁能解释以下关于自动实现属性的实际含义:“它们还使客户端代码能够创建对象。”?

我不明白这是什么意思。

谢谢。

【问题讨论】:

  • 自动属性的真正好处:DataBinding(这当然不适用于没有自定义 TypeDescriptor 的字段)。
  • 答案是,我觉得这只是 MSDN 的一个蹩脚的解释
  • 不幸的是,这是 MSDN 中许多糟糕的解释之一。

标签: c# .net


【解决方案1】:

我相信这指的是object initializer 语法,尽管尚不清楚为什么会这样。自动实现的属性和对象初始化器是分开的东西,不应该以这种方式链接在一起。

因此,使用如下所示的类:

public class Cat
{
    // Auto-implemented properties.
    public int Age { get; set; }
    public string Name { get; set; }
}

你可以像这样创建对象:

Cat cat = new Cat { Age = 10, Name = "Fluffy" };

注意:

正如 cmets 所说(以及关于对象初始化器的 MSDN 页面声明),您可以使用带有 any 可访问字段或属性的对象初始化器语法。同样,关于自动实现属性的 MSDN 页面甚至提到对象创建这一事实似乎是一个糟糕的文档决定。

【讨论】:

  • 你可以对公共字段做同样的事情。
  • 还有常规属性。基本上,可以使用Foo.x = y; 行设置的任何内容。
  • @leppie - 是的。来自 MSDN:Object initializers let you assign values to any accessible fields or properties
  • 和普通属性(私有字段,公共设置器)......所以虽然声明是真的,但对于非自动属性也是如此。
  • @Oded:在您编辑后删除了 Downvote,而我相信您和 jon 提到的初始化语法它们是不正确的,答案是让 OP 相信它们之间确实存在联系(除此之外,它们一起用于在类声明和创建新实例期间最小化代码)
【解决方案2】:

不幸的是,MSDN 页面上的描述很糟糕。

对象初始化语法 (new Foo { X = 10, Y = 20 }) 与自动实现的属性完全可分离

对象初始值设定项可与任何可设置的属性或字段一起使用(当“主属性”为只读时,甚至还有用于改变“子属性”的语法);您不必为此使用自动实现的属性。

虽然所有这些功能一起工作很好,但我相信至少了解它们是有用的。例如,可以在没有对象初始化器的情况下在 C# 2 中引入自动实现的属性 - 反之亦然。

【讨论】:

  • 不知道初始化只读属性的属性。这很漂亮。
  • @Anton:我经常看到它用于初始化集合:Foo f = new Foo { SomeCollection = { new Item(), new Item() };. Here the SomeCollection` 属性是读取-仅,但返回一个可以添加到的List<Item>
  • 没错,我想它是相似的——但集合是特殊情况的,不是吗? (ICollection 或任何有公共 Add 的东西,我忘记了:P)编辑 将其设为 IEnumerable 设为公共 Add。跨度>
  • @Anton:是的,IEnumerable 并添加它。我的观点是它的语法相同:= { ... } 而不是 = value
【解决方案3】:

我认为他们所说的

“它们还使客户端代码能够创建对象。”

是客户端代码可以初始化一个新的 ref 类型对象或将值类型对象分配给 auto 属性,而无需创建私有字段来保存数据。

Oded 有值类型的例子,所以让我们扩展他的 Cat 类

private class Cat
{
    // Auto-implemented properties.
    public int Age { get; set; }
    public string Name { get; set; }

    public List<Cat> Kittens { get; set; }
}

Cat cat = new Cat { Age = 10, Name = "Fluffy" }; //borrowed fluffy for this example
cat.Kittens = new List<Cat>();

cat.Kittens.Add( new Cat() { Age = 0, Name = "Pinky" } );
cat.Kittens.Add( new Cat() { Age = 0, Name = "Blinky" } );

【讨论】:

  • 同样,这里的自动属性没有什么独特之处。我认为 Jon Skeet 在这里赚到了钱:这只是一份措辞非常糟糕的文件。
【解决方案4】:

您可以通过自动实现属性值来访问另一个属性的值,从而为 getter 函数添加逻辑

 public string Status
    {
        get { return DeactivateDate != null ? "InActive" : "Active"; }
        private set { }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-04
    • 2021-04-14
    • 1970-01-01
    • 1970-01-01
    • 2014-03-16
    • 2015-05-23
    • 1970-01-01
    相关资源
    最近更新 更多