C#中的自动属性是什么?它们的用途是什么?

时间:2011-05-14 12:45:53

标签: c# .net syntax properties automatic-properties

有人可以提供C#中自动属性的简单解释,它们的用途,也许还有一些例子吗?请尽量以外行的方式保持事情!

11 个答案:

答案 0 :(得分:63)

如果属性访问器中不需要其他逻辑,则使用

自动属性 声明看起来像这样:

public int SomeProperty { get; set; }

它们只是语法糖,因此您不需要编写以下更冗长的代码:

 private int _someField;
 public int SomeProperty 
 {
    get { return _someField;}
    set { _someField = value;}
 }

答案 1 :(得分:30)

编辑:扩展一点,这些用于使类更容易拥有私有变量,但允许它们在类外部可见(无法修改它们)< / p>

哦,自动属性的另一个优点是你可以在接口中使用它们! (不允许任何类型的成员变量)

使用普通属性,您可以执行以下操作:

private string example;
public string Example 
{
    get { return example; }
    set { example = value; }
}

自动属性允许您创建非常简洁的内容:

public string Example { get; set; }

因此,如果您想创建一个只能在类中设置的字段,您可以这样做:

public string Example { get; private set; }

这相当于:

private string example;
public string Example 
{
    get { return example; }
    private set { example = value; }
}

或者在Java中:

private String example;

public String getExample() {
    return example;
}

public void setExample(String value) {
    example = value;
}

编辑:@Paya还提醒我:

答案 2 :(得分:13)

如果您问为什么要使用“属性”或“自动属性”,这就是它背后的设计理念。

一个重要的设计原则是,您从不将字段公开为公共字段,而是始终通过属性访问所有内容。这是因为你永远不知道何时访问某个字段,更重要的是它何时被设置。现在,很多时候,在设置或获取值时从不需要任何处理(例如,范围检查)。这就是创建自动属性的原因。它们是创建房产的简单,单线方式。它的后备存储由编译器创建。

虽然这是我对内部程序的所作所为,但对于那些专为公共使用而设计的产品(销售,开源等)可能更为重要。如果您使用自动属性,后来又决定需要在setget中执行其他操作,则可以轻松更改代码,而不会破坏公共界面。

<强>更新

作为对以下评论的澄清点,如果所有代码都是您自己的代码,那么不,它可能不会给您带来属性和字段之间的差异。但是,如果您正在设计一个将被其他人使用的库,那么在公共字段和属性之间来回切换将导致异常,除非首先重新编译使用该库的代码。

作为测试,我创建了一个库项目并声明了一个名为TestData的属性。我创建了一个全新的项目来使用这个库。一切都按预期工作。然后我将属性更改为公共字段(名称保持不变)并复​​制到新库DLL而不重新编译使用项目。结果是抛出异常,因为代码期望找到方法属性方法get_TestDataset_TestData,但不能通过方法访问字段。

Unhandled Exception: System.MissingMethodException: Method not found: 'Void TestLibrary.TesterClass.set_TestData(System.String)'.
   at TestLibraryConsumer.Program.Main(String[] args)

答案 3 :(得分:3)

它们只是一个编程快捷方式,可以为程序员节省一些按键。而不是输入所有这些:

private string _lastName;
public string LastName {
    get {
        return _lastName;
    }
    set {
        _lastName = value;
    }
}  

你可以输入:

public string LastName {
    get; set;
} 

让编译器自动生成其余部分。

答案 4 :(得分:1)

来自Auto-Implemented Properties (C# Programming Guide)

  

在C#3.0及更高版本中,当属性访问器中不需要其他逻辑时,自动实现的属性使属性声明更简洁。它们还使客户端代码能够创建对象   声明属性时,编译器会创建一个私有的匿名后备字段,只能通过属性的get和set访问器进行访问。

class Person
{
       public string Name { get; set; }
}

答案 5 :(得分:1)

我是早期版本的C#,为了使用属性,您需要创建一个字段来保存该值(称为Backing Store):

private string _something;
public string Prop { get { return _something; } }

从C#3.0开始,不再需要此要求,编译器将自动为您创建后备存储,因此无需声明_something字段。

您可以在此处详细了解此事:http://msdn.microsoft.com/en-us/library/bb384054.aspx

希望这有帮助。

答案 6 :(得分:1)

简化接受的答案,您可以也使用

public int SomeProperty { get; private set; }

它具有相同的效果,您不再需要为此创建另一个变量。

答案 7 :(得分:1)

许多人已经指出,自动属性是语法糖-一种编写简单属性的简写方式。我将处理公共变量和公共属性之间的差异,以及为什么在两者之间切换时需要重新编译。请执行以下操作:

public class MyClass
{
    public int MyPublicVariable = 0;

    public int MyPublicProperty
    {
        get;
        set;
    }
}

从概念上说,一旦编译完成,它们实际上将类似于以下内容:

public class MyClass
{
    public int MyPublicVariable = 0;

    private int MyPublicProperty = 0;

    public int get_MyPublicProperty()
    {
        return MyPublicProperty;
    }

    public void set_MyPublicProperty( int value )
    {
        MyPublicProperty = value;
    }
}

很久以前,就发明了属性,它是一种定义get和set方法对的快速简便的方法。在传达意图并确保一致性的同时,它使代码更易于阅读和理解。

MyClass myClass = new MyClass();

myClass.MyPublicVariable = 2;

myClass.MyPublicProperty = 2;

一旦编译,再次从概念上,它最终类似于以下内容:

MyClass myClass = new MyClass();

myClass.MyPublicVariable = 2;

myClass.set_MyPublicProperty( 2 );

因此,选择公共属性而不是公共变量的原因之一是,如果您需要在代码演变过程中使用不同的逻辑,则代码的使用者不一定需要重新编译。这就是为什么它通常被认为是最佳做法。这也是发明自动属性的原因-在保持最佳实践的同时加快代码编写速度。

也有一些关于接口的评论。接口本质上是一种契约,它保证在实现它们的任何类中某些方法的存在。从上面我们知道,属性代表一种或两种方法,因此它们在接口中可以正常工作。

希望这会有所帮助。

这是另一个有趣的例子:

public class MyClass
{
    private int[] _myArray = new int[ 5 ];

    public int MyArray[ int index ]
    {
        get
        {
            return _myArray[ index ];
        }
        set
        {
            _myArray[ index ] = value;
        }
     }
}
public class MyClass
{
    private int[] _myArray = new int[ 5 ];

    public int get_MyArray( int index )
    {
        return _myArray[ index ];
    }

    public void set_MyArray( int index, int value )
    {
        _myArray[ index ] = value;
    }
}
  

请注意:我不完全记得反编译时使用的方法签名   属性。我认为它是“ get_XXX”和“ set_XXX”,但可能是   其他非常相似的东西。只要有了解,   可能没有太大关系。最后,它们反正成为内存地址:-)

答案 8 :(得分:0)

除了在前面的答案中提到的方面之外,我还将注意到自动属性和字段之间的一些差异,因为它们的外观非常相似且用法几乎相同:

  • 可以在需要时轻松开发为“经典”属性,而无需与属性调用者达成任何合约
  • 在Visual Studio中进行开发时,允许在get / set上设置断点。当通过反射进行更改并且更改的来源不明显时,这特别有用

答案 9 :(得分:-1)

对于任何VB.NET阅读器,其实现方式略有不同。例如:

''' <summary>The property is declared and can be initialized.</summary>
Public Property MyProperty As String = "SomeValue"

但是,可以通过在下划线前面添加前缀来显式使用关联的字段:

Dim sConcat As String = _MyProperty + _MyProperty
_MyProperty = sConcat

并在外部代码中:

Dim sMyValue As String = oMyClassObj.MyProperty ' = "SomeValueSomeValue"

我个人更喜欢这种方法,因为在使用内部字段或可能公开的属性时,您可以在使用的代码中清楚地看到

答案 10 :(得分:-2)

使用以下代码:

using System;

class My Class
{
    public string Dummy { get; set; }

    public My Class()
    {
        Dummy = "I'm dummy property";
    }
}

class Program 
{
    static void Main() 
    {
            var my Class = new My Class();
             Console .Write Line (my Class .Dummy);
    }
}