Properties (C# Programming Guide)
A property is a member that provides a flexible mechanism to read, write, or compute the value of a private field. Properties can be used as if they're public data members, but they're special methods called accessors. This feature enables data to be accessed easily and still helps promote the safety and flexibility of methods.
Properties overview
- Properties enable a class to expose a public way of getting and setting values, while hiding implementation or verification code.
- A get property accessor is used to return the property value, and a set property accessor is used to assign a new value. An init property accessor is used to assign a new value only during object construction. These accessors can have different access levels. For more information, see Restricting Accessor Accessibility.
- The value keyword is used to define the value the
set
orinit
accessor is assigning. - Properties can be read-write (they have both a
get
and aset
accessor), read-only (they have aget
accessor but noset
accessor), or write-only (they have aset
accessor, but noget
accessor). Write-only properties are rare and are most commonly used to restrict access to sensitive data. - Simple properties that require no custom accessor code can be implemented either as expression body definitions or as auto-implemented properties.
Properties with backing fields
One basic pattern for implementing a property involves using a private backing field for setting and retrieving the property value. The get
accessor returns the value of the private field, and the set
accessor may perform some data validation before assigning a value to the private field. Both accessors may also perform some conversion or computation on the data before it's stored or returned.
The following example illustrates this pattern. In this example, the TimePeriod
class represents an interval of time. Internally, the class stores the time interval in seconds in a private field named _seconds
. A read-write property named Hours
allows the customer to specify the time interval in hours. Both the get
and the set
accessors perform the necessary conversion between hours and seconds. In addition, the set
accessor validates the data and throws an ArgumentOutOfRangeException if the number of hours is invalid.
public class TimePeriod
{
private double _seconds;
public double Hours
{
get { return _seconds / 3600; }
set
{
if (value < 0 || value > 24)
throw new ArgumentOutOfRangeException(nameof(value),
"The valid range is between 0 and 24.");
_seconds = value * 3600;
}
}
}
You could access properties to get and set the value as shown in the following example:
TimePeriod t = new TimePeriod();
// The property assignment causes the 'set' accessor to be called.
t.Hours = 24;
// Retrieving the property causes the 'get' accessor to be called.
Console.WriteLine($"Time in hours: {t.Hours}");
// The example displays the following output:
// Time in hours: 24
Expression body definitions
Property accessors often consist of single-line statements that just assign or return the result of an expression. You can implement these properties as expression-bodied members. Expression body definitions consist of the =>
symbol followed by the expression to assign to or retrieve from the property.
Read-only properties can implement the get
accessor as an expression-bodied member. In this case, neither the get
accessor keyword nor the return
keyword is used. The following example implements the read-only Name
property as an expression-bodied member.
public class Person
{
private string _firstName;
private string _lastName;
public Person(string first, string last)
{
_firstName = first;
_lastName = last;
}
public string Name => $"{_firstName} {_lastName}";
}
Both the get
and the set
accessor can be implemented as expression-bodied members. In this case, the get
and set
keywords must be present. The following example illustrates the use of expression body definitions for both accessors. The return
keyword isn't used with the get
accessor.
public class SaleItem
{
string _name;
decimal _cost;
public SaleItem(string name, decimal cost)
{
_name = name;
_cost = cost;
}
public string Name
{
get => _name;
set => _name = value;
}
public decimal Price
{
get => _cost;
set => _cost = value;
}
}
Auto-implemented properties
In some cases, property get
and set
accessors just assign a value to or retrieve a value from a backing field without including any extra logic. By using auto-implemented properties, you can simplify your code while having the C# compiler transparently provide the backing field for you.
If a property has both a get
and a set
(or a get
and an init
) accessor, both must be auto-implemented. You define an auto-implemented property by using the get
and set
keywords without providing any implementation. The following example repeats the previous one, except that Name
and Price
are auto-implemented properties. The example also removes the parameterized constructor, so that SaleItem
objects are now initialized with a call to the parameterless constructor and an object initializer.
public class SaleItem
{
public string Name
{ get; set; }
public decimal Price
{ get; set; }
}
Auto-implemented properties can declare different accessibilities for the get
and set
accessors. You commonly declare a public get
accessor and a private set
accessor. You can learn more in the article on restricting accessor accessibility.
Required properties
Beginning with C# 11, you can add the required
member to force client code to initialize any property or field:
public class SaleItem
{
public required string Name
{ get; set; }
public required decimal Price
{ get; set; }
}
To create a SaleItem
, you must set both the Name
and Price
properties using object initializers, as shown in the following code:
var item = new SaleItem { Name = "Shoes", Price = 19.95m };
Console.WriteLine($"{item.Name}: sells for {item.Price:C2}");
Related sections
- Using Properties
- Interface Properties
- Comparison Between Properties and Indexers
- Restricting Accessor Accessibility
- Auto-Implemented Properties
C# Language Specification
For more information, see Properties in the C# Language Specification. The language specification is the definitive source for C# syntax and usage.
See also
Feedback
https://aka.ms/ContentUserFeedback.
Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see:Submit and view feedback for