关于自动属性:C#auto属性与普通字段

C# autoproperty vs normal fields

本问题已经有最佳答案,请猛点这里访问。

foo.something和bar.something在这个例子中有什么区别吗?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Foo
{
    public string Something;
}

class Bar
{
    public string Something{get; set;}
}

class Program
{
    static void Main(string[] args)
    {
        var MyFoo = new Foo();
        MyFoo.Something ="Hello: foo";
        System.Console.WriteLine(MyFoo.Something);

        var MyBar = new Bar();
        MyBar.Something ="Hello: bar";
        System.Console.WriteLine(MyBar.Something);
        System.Console.ReadLine();
    }
}

他们的行为完全一样。如果他们这样做,为什么不使用像foo这样的平原?在Java中,我们使用设置器来执行新的不变量,而不破坏代码和吸引子返回安全数据,但是在C语言中,您总是可以将FO重写为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Foo
{
    private string _Something;
    public string Something
    {
        get {
            //logic
            return _Something;
            }
        set {
            //check new invariant
            _Something = value;
            }
    }
}

旧代码不会被破坏。


0

不,他们没有。

  • 字段不能用于数据绑定(至少在某些绑定实现中)
  • 以后可以为属性添加更多逻辑,而不破坏源代码或二进制兼容性
  • 属性不能通过引用传递
  • 不能向自动实现的属性添加初始值设定项
  • 它们在反射方面显然是不同的。
  • 从哲学上讲,属性在逻辑上是API的一部分,而字段是实现细节

in c# you can always rewrite Foo into this: [...]

好吧,如果你不关心二进制或源代码的兼容性,你可以,是的。在某些情况下,这实际上不是一个问题——在其他情况下,这是一个非常非常非常重要的问题。为什么不从一开始就选择公开您的API而不是您的实现细节呢?这不像在代码中添加{ get; set; }会增加很多混乱…

欲了解更多信息,请参阅我的文章。


Foo.Something是一个字段,Bar.Something是一个自动实现的属性。这是一个巨大的不同。

您可以像访问字段一样访问属性,但在内部,访问属性时会调用set/get方法。

所以当你说myBar.Something ="asdf"时,c编译器会将其转换为对setter方法的调用:myBar.set_Something("asdf")。setter和getter方法是自动为您生成的,以及实际值的支持字段。

通过使用get和set方法将Foo.Something更改为属性,您将破坏二进制兼容性,这意味着您必须重新编译使用Foo.Something的所有程序集(当它仍然是字段时)。


public string Something{get; set;}只是语法上的糖分;编译器实际上将其扩展为方法。因此,仅仅为了这个目的,把所有的get; set;字段都放在这里没有什么意义。


1)您可以添加私有访问器来获取或设置和控制对属性的访问。

1
public object MyProp {get; private set;}

你可以在任何地方读道具,但只能在课堂上写

2)您可以将一些逻辑连接到读/写属性。如果是字段,则不能执行任何其他操作

3)不能序列化字段


属性(包括自动属性)的getter和setter具有方法调用开销。应避免使用公共场所,以保持物品清洁。