简体   繁体   English

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

[英]What are Automatic Properties in C# and what is their purpose?

Could someone provide a very simple explanation of Automatic Properties in C#, their purpose, and maybe some examples?有人可以对 C# 中的自动属性、它们的目的以及一些示例提供一个非常简单的解释吗? Try to keep things in layman's terms, please!请尽量用外行的话说!

Automatic Properties are used when no additional logic is required in the property accessors.当属性访问器中不需要额外的逻辑时,使用自动属性。
The declaration would look something like this:声明看起来像这样:

public int SomeProperty { get; set; }

They are just syntactic sugar so you won't need to write the following more lengthy code:它们只是语法糖,因此您无需编写以下更冗长的代码:

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

Edit: Expanding a little, these are used to make it easier to have private variables in the class, but allow them to be visible to outside the class (without being able to modify them)编辑:扩展一点,这些用于使类中的私有变量更容易,但允许它们在类外部可见(不能修改它们)

Oh, and another advantage with automatic properties is you can use them in interfaces !哦,自动属性的另一个优点是您可以在接口中使用它们 (Which don't allow member variables of any kind) (不允许任何类型的成员变量)

With normal properties, you can do something like:使用普通属性,您可以执行以下操作:

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

Automatic properties allows you to create something really concise:自动属性允许你创建一些非常简洁的东西:

public string Example { get; set; }

So if you wanted to create a field where it was only settable inside the class, you could do:因此,如果您想创建一个只能在类中设置的字段,您可以执行以下操作:

public string Example { get; private set; }

This would be equivalent to:这相当于:

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

Or in Java:或者在 Java 中:

private String example;

public String getExample() {
    return example;
}

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

Edit: @Paya also alerted me to:编辑:@Paya 还提醒我:

If you are asking why you would use Properties or Automatic Properties, this is the design philosophy behind it.如果您问为什么要使用属性或自动属性,这就是其背后的设计理念。

One important design principle is that you never expose fields as public, but rather always access everything via properties.一项重要的设计原则是永远不要将字段公开为公共字段,而是始终通过属性访问所有内容。 This is because you can never tell when a field is accessed and more importantly when it is set.这是因为你永远无法判断一个字段何时被访问,更重要的是它何时被设置。 Now, a lot of the time, there is never any processing needed while setting or getting the value (for example, range checking).现在,很多时候,在设置或获取值时不需要任何处理(例如,范围检查)。 This is why Automatic Properties were created.这就是创建自动属性的原因。 They are a simple, one-line way of creating a property.它们是创建属性的一种简单的单行方式。 The backing store for it is created by the compiler.它的后备存储是由编译器创建的。

While this is what I do even for my internal programs, it is probably more important for ones designed for public use (for sale, open source, etc).虽然这就是我什至为我的内部程序所做的,但对于为公共使用而设计的程序(用于销售、开源等)来说,这可能更为重要。 If you use an Automatic Property and later decide that you need to do something else in the set or get , you can easily change your code without breaking the public interface.如果您使用自动属性,然后决定需要在setget执行其他操作,则可以轻松更改代码而不会破坏公共接口。

Update更新

As a point of clarification to a comment below, if all of the code is your own, then no, it may not make much of a difference between a property and a field to you.作为对下面评论的澄清点,如果所有代码都是您自己的,那么不,它可能对您来说属性和字段之间没有太大区别。 But, if you are designing a library that will be consumed by others then switching back and forth between public fields and properties will cause exceptions unless the code using the library is recompiled first.但是,如果您正在设计一个将被其他人使用的库,那么除非首先重新编译使用该库的代码,否则在公共字段和属性之间来回切换将导致异常。

As a test, I created a library project and declared a property called TestData .作为测试,我创建了一个库项目并声明了一个名为TestData的属性。 I created a whole new project just to consume this library.我创建了一个全新的项目只是为了使用这个库。 All worked as expected.一切都按预期工作。 I then changed the property to a public field (the name stayed the same) and copied over the new library DLL without recompiling the consuming project.然后我将该属性更改为公共字段(名称保持不变)并复​​制到新库 DLL 上,而无需重新编译使用项目。 The outcome was an exception thrown as the code was expecting to find the methods property methods get_TestData and set_TestData , but fields are not accessed via methods.结果是抛出异常,因为代码期望找到方法属性方法get_TestDataset_TestData ,但不通过方法访问字段。

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

Many people have already stated that auto properties are syntactic sugar - a shorthand way of writing simple properties.许多人已经说过 auto 属性是语法糖 - 一种编写简单属性的速记方式。 I will deal with the differences between a public variable and a public property and why, when switching between the two, you would need to recompile.我将处理公共变量和公共属性之间的差异,以及为什么在两者之间切换时需要重新编译。 Take the following:采取以下措施:

public class MyClass
{
    public int MyPublicVariable = 0;

    public int MyPublicProperty
    {
        get;
        set;
    }
}

Once compiled, conceptually , it actually ends up being similar to the following:一旦编译,从概念上讲,它实际上最终类似于以下内容:

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;
    }
}

A long time ago, properties were invented to be a quick and easy way to define pairs of get and set methods.很久以前,属性被发明为一种快速简便的定义 get 和 set 方法对的方法。 It made code more readable and easier to understand as they conveyed intent and ensured consistency.它使代码更具可读性和更容易理解,因为它们传达了意图并确保了一致性。

MyClass myClass = new MyClass();

myClass.MyPublicVariable = 2;

myClass.MyPublicProperty = 2;

Once compiled, again conceptually , it ends up being similar to the following:再次在概念上编译后,它最终类似于以下内容:

MyClass myClass = new MyClass();

myClass.MyPublicVariable = 2;

myClass.set_MyPublicProperty( 2 );

So, one of the reasons for preferring public properties over public variables is if you need to use different logic as your code evolves then consumers of your code don't necessarily need to re-compile.因此,更喜欢公共属性而不是公共变量的原因之一是,如果您需要随着代码的发展使用不同的逻辑,那么您的代码的使用者不一定需要重新编译。 This is why it is often considered best practice.这就是为什么它通常被认为是最佳实践的原因。 It is also the reason auto properties were invented - to speed along code writing whilst maintaining this best practice.这也是发明自动属性的原因 - 在保持这种最佳实践的同时加快代码编写速度。

There has also been some comments about interfaces.也有一些关于接口的评论。 Interfaces are essentially a contract that guarantees the presence of certain methods within any class implementing them.接口本质上是一种契约,它保证在实现它们的任何类中存在某些方法。 As we know from the above, properties represent one or two methods so they work just fine in interfaces.正如我们从上面知道的,属性代表一两个方法,因此它们在接口中工作得很好。

Hope this helps a little.希望这有所帮助。

Here is another example that may be of interest:这是另一个可能感兴趣的示例:

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;
    }
}

Please note: I cannot exactly remember the method signatures used when decompiling properties.请注意:我无法完全记住反编译属性时使用的方法签名。 I think it is 'get_XXX' and 'set_XXX' but it could be something else that is very similar.我认为它是“get_XXX”和“set_XXX”,但它可能是其他非常相似的东西。 As long as the understanding is there, it probably doesn't matter too much.只要理解在那里,它可能并没有太大关系。 In the end, they all become memory addresses anyway :-)最后,无论如何它们都变成了内存地址:-)

They are just a coding shortcut to save the programmer a few keystrokes.它们只是一种编码快捷方式,可以节省程序员的几次按键操作。 Instead of typing all this:而不是输入所有这些:

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

you can just type:你可以输入:

public string LastName {
    get; set;
} 

and let the compiler generate the rest automatically.并让编译器自动生成其余部分。

Simplifying the accepted answer, you can also use :简化接受的答案,您还可以使用

public int SomeProperty { get; private set; }

It has the same effect and you no longer have to create another variable for that.它具有相同的效果,您不再需要为此创建另一个变量。

From Auto-Implemented Properties (C# Programming Guide) :来自自动实现的属性(C# 编程指南)

In C# 3.0 and later, auto-implemented properties make property-declaration more concise when no additional logic is required in the property accessors.在 C# 3.0 及更高版本中,当属性访问器中不需要额外的逻辑时,自动实现的属性使属性声明更加简洁。 They also enable client code to create objects.它们还使客户端代码能够创建对象。
When you declare a property, the compiler creates a private, anonymous backing field that can only be accessed through the property's get and set accessors.当您声明一个属性时,编译器会创建一个私有的匿名支持字段,该字段只能通过该属性的 get 和 set 访问器进行访问。

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

Iמ earlier versions of C#, in order to use properties, you would need to create a field to hold the value (called a Backing Store):在 C# 的早期版本中,为了使用属性,您需要创建一个字段来保存值(称为后备存储):

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

Starting with C# 3.0, this requirement is no longer needed, and the compiler will automatically create the backing store for you, so there's no need to declare the _something field.从 C# 3.0 开始,不再需要此要求,编译器会自动为您创建后备存储,因此无需声明 _something 字段。

You can read more on this matter here: http://msdn.microsoft.com/en-us/library/bb384054.aspx您可以在此处阅读有关此问题的更多信息: http : //msdn.microsoft.com/en-us/library/bb384054.aspx

Hope this helps.希望这可以帮助。

Besides mentioned aspects in the previous answer, I would also notice some differences between automatic properties and fields since they look very similar and their usage is virtually the same:除了前面答案中提到的方面,我还会注意到自动属性和字段之间的一些差异,因为它们看起来非常相似并且它们的用法几乎相同:

  • can be easily developed into "classic" properties when needed without breaking any contract with property callers可以在需要时轻松开发为“经典”属性,而不会破坏与属性调用者的任何合同
  • allow breakpoints on get / set when developing in Visual Studio.在 Visual Studio 中开发时允许在 get/set 上设置断点。 This is especially useful when changes are done through reflection and the source of change is not obvious当通过反射完成更改并且更改源不明显时,这尤其有用

For any VB.NET readers, this is implemented slightly differently.对于任何 VB.NET 阅读器,实现方式略有不同。 Eg:例如:

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

However, the associated field is explicitly available by prefixing an underscore:但是,关联字段可通过添加下划线前缀来显式使用:

Dim sConcat As String = _MyProperty + _MyProperty
_MyProperty = sConcat

And in external code:在外部代码中:

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

Personally, I like this approach better as you can clearly see in your consuming code when you're working with internal fields or possibly-exposed properties.就我个人而言,我更喜欢这种方法,因为当您处理内部字段或可能暴露的属性时,您可以在使用代码中清楚地看到。

Use below code:使用以下代码:

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);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM