Свойство (Property)
Свойство (Property) в C# предоставя контролиран достъп до полетата на класа чрез get и set. Свойствата комбинират функционалността на полета и методи.
Основни видове свойства
public class Person
{
// Автоматично имплементирано свойство
public string FirstName { get; set; }
// Свойство с backing field
private string lastName;
public string LastName
{
get { return lastName; }
set { lastName = value; }
}
// Само за четене
public string FullName
{
get { return $"{FirstName} {LastName}"; }
}
// Изчислимо свойство
public int Age
{
get { return DateTime.Now.Year - DateOfBirth.Year; }
}
}
Модификатори за достъп
public class Account
{
// Публичен get, приватен set
public decimal Balance { get; private set; }
// Защитен set
public string AccountNumber { get; protected set; }
// Различни модификатори за get и set
public string Pin
{
protected get { return pin; }
private set { pin = value; }
}
// Само за инициализация
public DateTime CreatedDate { get; init; }
}
Валидация в свойства
public class Product
{
private decimal price;
public decimal Price
{
get { return price; }
set
{
if (value < 0)
{
throw new ArgumentException("Price cannot be negative");
}
price = value;
}
}
private string name;
public string Name
{
get { return name; }
set
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentException("Name cannot be empty");
}
name = value;
}
}
}
Expression-bodied свойства
public class Circle
{
public double Radius { get; set; }
// Expression-bodied get-only свойство
public double Area => Math.PI * Radius * Radius;
// Expression-bodied get и set
private double diameter;
public double Diameter
{
get => diameter;
set => diameter = value;
}
}
Автоматични свойства с default стойности
public class Configuration
{
// Default стойности
public string Host { get; set; } = "localhost";
public int Port { get; set; } = 8080;
public bool IsEnabled { get; set; } = true;
public List<string> Tags { get; set; } = new List<string>();
}
Индексатори
public class StringDictionary
{
private Dictionary<string, string> items = new Dictionary<string, string>();
// Индексатор
public string this[string key]
{
get { return items[key]; }
set { items[key] = value; }
}
}
// Използване
var dict = new StringDictionary();
dict["key"] = "value";
Свойства в интерфейси
public interface IEntity
{
int Id { get; set; }
DateTime CreatedDate { get; }
bool IsActive { get; set; }
}
public class User : IEntity
{
public int Id { get; set; }
public DateTime CreatedDate { get; } = DateTime.Now;
public bool IsActive { get; set; } = true;
}
Lazy Loading
public class Document
{
private byte[] content;
public byte[] Content
{
get
{
if (content == null)
{
content = LoadContent();
}
return content;
}
}
private byte[] LoadContent()
{
// Зареждане на съдържанието
return File.ReadAllBytes("document.pdf");
}
}
INotifyPropertyChanged имплементация
public class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private string name;
public string Name
{
get { return name; }
set
{
if (name != value)
{
name = value;
OnPropertyChanged(nameof(Name));
OnPropertyChanged(nameof(FullName));
}
}
}
public string FullName => $"Mr. {Name}";
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Добри практики
- Именуване
// Добре - PascalCase за публични свойства
public string FirstName { get; set; }
// Лошо
public string firstName { get; set; }
- Валидация
public string Email
{
get => email;
set
{
if (!IsValidEmail(value))
throw new ArgumentException("Invalid email format");
email = value;
}
}
- Backing Fields
// Добре - подчертавка за private полета
private string _firstName;
public string FirstName
{
get => _firstName;
set => _firstName = value;
}
- Изчислими свойства
// Добре - кратко и ясно
public bool IsAdult => Age >= 18;
// Лошо - излишна сложност
public bool IsAdult
{
get
{
if (Age >= 18)
return true;
return false;
}
}
- Документация
/// <summary>
/// Gets or sets the user's email address.
/// </summary>
/// <exception cref="ArgumentException">
/// Thrown when the email format is invalid.
/// </exception>
public string Email { get; set; }
Пример:
class User {
private string name;
public string Name {
get { return name; }
set { name = value; }
}
}