"prop"和"full property"有什么区别?

19

下面这两段代码有区别吗?还是说上面的只是下面一段的简写形式?

public string Name { get; set; }
并且
private string _Name;
public string Name
{
    get { return _Name; }
    set { _Name = value; }
}

从MSDN关于自动属性的文章中可以得知:"...编译器会创建一个私有的匿名后备字段,只能通过属性的get和set访问器进行访问" - http://msdn.microsoft.com/en-us/library/bb384054.aspx - Adam Ralph
7个回答

14
除了你需要在类构造函数中使用“Default Name”进行初始化之外,唯一的区别就是_Name只能在类内部可见。如果类内部直接引用_Name而不是Name,一切都会正常工作,但稍后如果你在Name中添加一些逻辑,由于类内部使用的是_Name,这些逻辑将不会被调用。
示例:
private string _Name = "Default Name";
public string Name
{
   get { return _Name.Left(42); }  // Changed the getter
   set { _Name = value; }
}

void MyOtherMethod()
{
   string foo = _Name; // Referencing the private field accidentally instead of the public property.
   // Do something with foo
}

4

属性方法的基本行为和目的几乎相同。但主要区别在于实现方式。两种方法之间的区别在于

public string Name{get;set;}

并且

 private string _Name;
        public string Name
        {
            get { return _Name; }
            set { _Name=value;  }
        }

如果您使用短属性语法(在框架3.0或更高版本中引入) ,则该属性字符串永远不会初始化,即如果您在任何地方直接使用“Name”属性而没有将值设置为它,则它将返回一个NULL值。但是,如果您使用第二种语法来初始化属性值,则它将返回一个空字符串,因为当您初始化一个字符串时,它被初始化为一个空值而不是NULL。因此,如果您使用完整的属性方法返回属性值而没有使用初始化,则它将始终返回一个空字符串而不是NULL值。


我已经测试过了,在这两种情况下,name的返回值都是null: https://dotnetfiddle.net/jqFXdl (也在.NET Framework 2.0、3.0和3.5中进行了测试) - Antonio Rodríguez
提供的答案非常陈旧,不适用于较新版本的C#。自动属性初始化器在过去几年中发生了很大变化。 - Sankalp

3
我认为编译后的代码没有任何区别。但如果您想要添加默认值(可以在构造函数中以简短形式完成),或者需要在getter或setter中添加其他代码,那么可能会选择完整方式。 编辑:实际上,您的代码是错误的,应该是
private string _Name;
public string Name
{
   get { return _Name; }
   set { _Name = value; }//change here
}

not...

value = _Name;

1
意识到这个问题已经很老了,在C# 6.0中,自动属性可以使用默认值进行初始化。请参阅https://dev59.com/53VD5IYBdhLWcg3wQJKT获取更多信息。 - manotheshark

2

其中一个区别是,当您这样做时,可以在私有字符串上设置默认值。

private string _Name = "Default Name";
public string Name
{
   get { return _Name; }
   set { value = _Name; }
}

一旦编译完成,你展示的这两个例子就是相同的。


1

对于第二种形式的特定实现,两者是等价的。因为如果你只写第一种形式,编译器将生成几乎相同的代码。

也就是说,编译器会添加代码:

public string Name{get;set;}

使它看起来像这样:

private string generatedCode_Name;
public string Name
{
      get { return generatedCode_Name; }
      set { generatedCode_Name = value; }
}

顺便说一下,这是不正确的

set { value = _Name; } //I believe its a typo!

我想你的意思是:

set {  _Name = value; }

1

这只是一个简单的表单,底层变量仍然作为支持后备字段生成(数据存储的位置),但自动生成 - 如果你只是获取和设置,而不需要在任何访问器中具体实现细节,这是非常有用的。


0

对于所写的示例,它们是完全等效的。

自动实现属性是一种语法糖,用于解决恰好这种类型的情况,在该情况下,属性仅用于避免具有无额外逻辑的公共字段的情况。然而,自动实现属性为您提供了所有属性的好处,包括元数据。这是一个相当古老但仍然相关的链接,更详细地解释了它们。

在幕后,编译器生成一个类似于您自己的后备字段。


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