C#自动实现属性

10

我对自动属性这一概念还比较陌生,但在 Microsoft 网站上看到以下说明:

在 C# 3.0 及以后的版本中,当属性访问器中不需要其他逻辑时,使用自动属性可以使属性声明更加简洁。 同时,它们还允许客户端代码创建对象。 当您声明一个属性时,编译器会创建一个私有的匿名成员变量,在属性的 get 和 set 访问器中才能访问到该成员变量。

-- 自动实现属性 (MSDN)

请问:"同时,它们还允许客户端代码创建对象。" 这句话是什么意思呢?

我不太明白这句话的含义。

谢谢。


请问如何为C#自动属性设置默认值? - user195488
1
自动属性的真正好处:数据绑定(当然,这对于没有自定义“TypeDescriptor”的字段无效)。 - leppie
3
答案是,那只是 MSDN 上一个糟糕的解释,我感觉。 - Kieren Johnstone
3
遗憾的是,MSDN 上有很多糟糕的解释之一。 - Matthew Scharley
4个回答

6
我认为这是指对象初始化语法,但为什么会如此并不清楚。自动属性和对象初始化器是两个不同的事物,不应该以这种方式联系在一起。
因此,对于一个类,它看起来像这样:
public class Cat
{
    // Auto-implemented properties.
    public int Age { get; set; }
    public string Name { get; set; }
}

您可以像这样创建对象:
Cat cat = new Cat { Age = 10, Name = "Fluffy" };

注意:
正如注释所说(以及对象初始化器的MSDN页面所声明的),您可以使用对象初始化器语法来访问任何可访问的字段或属性。再次强调,自动实现属性的MSDN页面甚至提到对象创建的事实似乎是一个糟糕的文档决策。

6
你可以对公共字段做同样的操作。 - leppie
3
还有一般的属性。基本上,所有可以用 Foo.x = y; 这样的语句来设置的内容都包括在内。 - Matthew Scharley
2
而对于普通属性(私有字段,公共设置器)... 因此,虽然该语句是正确的,但对于非自动属性也是正确的。 - Anders Forsgren
@Oded:不是我,但“private class”让我有点生气 ;P - leppie
1
@Oded:您进行了编辑后,取消了我对答案的负评。虽然我和Jon认为它们是引用初始化程序语法,但他们是不正确的,而且回答让OP相信它们之间确实存在联系(除了它们在声明类和创建新实例时一起使用以最小化代码)。 - Julien Roncaglia
显示剩余2条评论

4
很不幸,MSDN页面上的描述很糟糕。
对象初始化器语法(new Foo { X = 10, Y = 20 })与自动实现属性是完全可分离的。
对象初始化器可以与任何可设置的属性或字段一起使用(甚至有用于在“主属性”为只读时变异“子属性”的语法);您不必为此使用自动实现属性。
虽然所有这些功能都能协同工作,但我认为至少了解它们各自的用途是有用的。例如,自动实现属性可以在没有对象初始化器的情况下在C# 2中引入-反之亦然。

不知道如何初始化只读属性的属性。这很聪明。 - anton.burger
@Anton:我主要是看到它用于初始化集合:Foo f = new Foo { SomeCollection = { new Item(), new Item() };。这里的 SomeCollection 属性是只读的,但返回一个可以添加元素的 List<Item> - Jon Skeet
是的,我想它们很相似 - 但集合是特殊情况,不是吗?(要么是ICollection,要么是任何具有公共Add的东西,我忘记了:P)编辑变成IEnumerable和公共Add - anton.burger
@Anton:没错,就是IEnumerable和Add。我的意思是它们的语法是一样的:= { ... }而不是= value - Jon Skeet

1

我认为他们所说的是

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

这意味着客户端代码可以初始化一个新的引用类型对象或将值类型对象分配给自动属性,而无需创建一个私有字段来保存数据。

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说得很对:这只是一份措辞非常不当的文件。 - Matthew Scharley

-1

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接