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 as shown in the following example, the compiler creates a private, anonymous backing field can only be accessed through the property's get and set accessors.
The following example shows a simple class that has some auto-implemented properties:
// This class is mutable. Its data can be modified from // outside the class. class Customer { // Auto-Impl Properties for trivial get and set public double TotalPurchases { get; set; } public string Name { get; set; } public int CustomerID { get; set; } // Constructor public Customer(double purchases, string name, int ID) { TotalPurchases = purchases; Name = name; CustomerID = ID; } // Methods public string GetContactInfo() {return "ContactInfo";} public string GetTransactionHistory() {return "History";} // .. Additional methods, events, etc. } class Program { static void Main() { // Intialize a new object. Customer cust1 = new Customer ( 4987.63, "Northwind",90108 ); //Modify a property cust1.TotalPurchases += 499.99; } }
The class that is shown in the previous example is mutable. Client code can change the values in objects after they are created. In complex classes that contain significant behavior (methods) as well as data, it is often necessary to have public properties. However, for small classes or structs that just encapsulate a set of values (data) and have little or no behaviors, it is recommended to make the objects immutable by declaring the set accessor as private. For more information, see How to: Implement an Immutable Class That Has Auto-Implemented Properties (C# Programming Guide).
Attributes are permitted on auto-implemented properties but obviously not on the backing fields since those are not accessible from your source code. If you must use an attribute on the backing field of a property, just create a regular property.
Reference
Contrary to the original documentation, attributes are permitted on auto-implemented properties, including their accessors.
public class LightweightCustomer
{
public double TotalPurchases { get; set; }
public string Name { get; set; }
[ XmlAttribute ] public int CustomerID { get; set; }
}
It's possible the documentation meant to say that attributes cannot be applied to the backing fields since these are automatically generated by the compiler, but that would be stating rather the obvious.
CS Team: This was clarified in later versions of the documentation. Thanks.
class Customer
{
public string name{ get; set; }
}
And you want to this for a certain reason:class CustomerThis will raise a compilation error that the setter lacks implementation.
{
public string name{ get {return "the great unknown"}; set; }
}
// Auto-Impl Properties for trivial get and set
public double TotalPurchases { get; set; }
publicstring Name { get; set; }
publicint CustomerID { get; set; }
// Regular field
public double TotalPurchases ;
publicstring Name ;
publicint CustomerID ;
The major advantages of using the former over the latter is:
a) You have the flexibility of moving to standard properties (with backing field etc) down the track without altering the public interface of the class.
b) Most binding works with properties and not public fields. See
http://stackoverflow.com/questions/842575/why-does-wpf-support-binding-to-properties-of-an-object-but-not-fields
for instance.
Probably obvious to most, but when overriding a class with a property that has only a GET accessor, auto-implemented properties cannot be used, as they require both GET and SET.
The use of {get; private set;} is not equivalent, and produces a compile time error.
The behaviour is logical and consistent, but it may be unexpected.
In an interface the property must have a signature of {get;} only if {get; private set;} is to be placed in the concrete class, this seems confusing.
Hi,
Ive made the property initialization available to all the properties of the current class using reflection, i want to share with you the piece of code
foreach (PropertyInfo propiedad inthis.GetType().BaseType.GetProperties(
BindingFlags.Instance |BindingFlags.Public |BindingFlags.DeclaredOnly |BindingFlags.Static))
{
if (propiedad.PropertyType.FullName == 0.GetType().FullName){propiedad.SetValue(this, 0, null);}elseif (propiedad.PropertyType.FullName == string.Empty.GetType().FullName){propiedad.SetValue(this, string.Empty, null);}elseif (propiedad.PropertyType.FullName == DateTime.Now.GetType().FullName){propiedad.SetValue(this, DateTime.MinValue, null);}elseif (propiedad.GetType() == typeof(List<>)){// propiedad.SetValue(this, Activator.CreateInstance(typeof(List<>).GetType()), null);propiedad.SetValue(this, newList<object>(), null);}
}
As you can see, it works only with integers, strings, and datetime types, but you can add as many as you want; Maybe this comparation method is not the most efficient (string vs string) but i made it very quickly and also by some reason i couldnt use a switch statement.
Maybe someone clever can help us to make the List<T> initialization possible, in that case pls let me know... alejandro.aleman at google
Remarks!
The BaseType inside the foreach declaration is because the properties in MY class resides on the BaseClass, so you can remove it if your class does not inherit from any other.
public string Name { get; private set; } = "Fred"This means that strings and objects always default to null so you have to initialize them elsewhere. This defeats the point of the shorthand syntax.
I have seen the argument that these were added purely for Linq, but if this is the case why does the "prop" snippet produce automatic properties. This makes it even slower to produce a "fully blown" property definition, so things are actually worse than they were. Nice!
Go to Microsoft Connect to vote for the addition of initialization: http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=361647
Edit 3/2/2009: The "shorthand syntax" to which you are referring does not exist for explicit properties either. For example, the following code is not valid:
public string Name { get { return name } private set { name = value; } } = "Fred"
string name;
The C# compiler will complain about the syntax used above. However, it is of course allowable to initialize an explicit backing field inline:
public string Name { get { return name } private set { name = value; } }
string name = "Fred";
An automatic property cannot be initialized inline like a field. This is a "limitation" of automatic properties that you must live with if you choose to use them, because they don't expose the backing field to user code (it is automatic). Alternatively, you can initialize an automatic property in a constructor to achieve the same result:
class Person
{
public string Name { get; private set; }
public Person()
{
Name = "Fred";
}
}
See bug ID: 360658
Contrary to what the documentation suggests, it is not possible to define an auto-implemented property that uses the same behavior as the C# readonly keyword (when applied to an explicit backing field). The link to the readonly topic should be removed, at the very least.
Using private set will define an auto-implemented property with a read-only public contract, although this leaves open the possibility for the value to change after the constructor has been invoked; behavior that is prevented by defining a property without a set accessor and applying the readonly keyword to the backing field.
class Class1
{
public string NotReadOnly { get; private set; }
public string TrulyReadOnly { get { return trulyReadOnly; } }
readonly string trulyReadOnly = "value";
public void SetReadOnlyAfterInitialization()
{
// This assignment is permitted by the compiler
NotReadOnly = "this property is not actually read-only.";
// Compile-time error: Property or indexer 'TrulyReadOnly' cannot be assigned to -- it is read only
TrulyReadOnly = "this property is actually read-only.";
}
}
While it's a marginal case in current practice, auto-implemented properties can be made write-only (a.k.a. data-sinks or black-holes) in a symetryc way to read-only ones. The following code compiles and works as it could be expected:
namespace MyConsoleApplication {
class Program {
public static string MyWriteOnlyAutoImplementedProperty { private get; set; }
static void Main(string[] args) {
MyWriteOnlyAutoImplementedProperty = "Some text"; // Ok
string MyString = MyWriteOnlyAutoImplementedProperty // Ok: we can still access private members from inside Program
}
}
class MyClass {
public void MyMethod() {
MyWriteOnlyAutoImplementedProperty = "Some text"; // Ok, we are fine as long as we just write
// string MyString = MyWriteOnlyAutoImplementedProperty // Error!
}
}
}
Uncommenting the line marked as "Error!" generates the message "The property or indexer 'MyConsoleApplication.Program.MyWriteOnlyAutoImplementedProperty' cannot be used in this context because the get accessor is inaccessible" at compile time.
The utility of this capability is out of the scope of this comment: it is only intended to point out the existence of the feature.