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

有没有人可以简单地解释一下 C # 中的自动属性,它们的用途,或者一些例子?请尽量用通俗易懂的语言来表达!

91521 次浏览

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:

private String example;


public String getExample() {
return example;
}


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

Edit: @Paya also alerted me to:

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.

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

From Auto-Implemented Properties (C# Programming Guide):

In C# 3.0 and later, auto-implemented properties make property-declaration more concise when no additional logic is required in the property accessors. 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.

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):

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.

You can read more on this matter here: http://msdn.microsoft.com/en-us/library/bb384054.aspx

Hope this helps.

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.

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. 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. 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.

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

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.

For any VB.NET readers, this is implemented slightly differently. 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);
}
}

Many people have already stated that auto properties are syntactic sugar - a shorthand way of writing simple properties. 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. 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. As long as the understanding is there, it probably doesn't matter too much. In the end, they all become memory addresses anyway :-)

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. This is especially useful when changes are done through reflection and the source of change is not obvious