C Sharp 计算属性
外观
C#计算属性[编辑 | 编辑源代码]
计算属性(Computed Properties)是C#中一种特殊的属性类型,它不直接存储值,而是通过计算或逻辑来获取或设置值。计算属性通常用于封装字段访问逻辑,提供更灵活的数据操作方式。
基本概念[编辑 | 编辑源代码]
计算属性与普通属性的主要区别在于:
- 普通属性通常直接对应一个私有字段(backing field)
- 计算属性的值是在访问时动态计算的
计算属性通常只包含get访问器,或者包含自定义逻辑的get/set访问器。
语法结构[编辑 | 编辑源代码]
基本语法如下:
public 数据类型 属性名
{
get
{
// 计算逻辑
return 计算结果;
}
[set
{
// 设置逻辑(可选)
}]
}
基本示例[编辑 | 编辑源代码]
下面是一个简单的计算属性示例,计算矩形的面积:
public class Rectangle
{
public double Width { get; set; }
public double Height { get; set; }
// 计算属性
public double Area
{
get
{
return Width * Height;
}
}
}
// 使用示例
Rectangle rect = new Rectangle { Width = 5, Height = 10 };
Console.WriteLine(rect.Area); // 输出: 50
高级用法[编辑 | 编辑源代码]
带条件的计算属性[编辑 | 编辑源代码]
计算属性可以包含条件逻辑:
public class Temperature
{
private double celsius;
public double Celsius
{
get => celsius;
set => celsius = value;
}
public double Fahrenheit
{
get => (celsius * 9 / 5) + 32;
set => celsius = (value - 32) * 5 / 9;
}
}
基于集合的计算[编辑 | 编辑源代码]
计算属性常用于集合操作:
public class ShoppingCart
{
public List<CartItem> Items { get; } = new List<CartItem>();
public decimal TotalPrice
{
get
{
return Items.Sum(item => item.Price * item.Quantity);
}
}
}
性能考虑[编辑 | 编辑源代码]
计算属性每次被访问时都会执行计算,因此对于计算成本高的操作,应考虑缓存结果:
public class ExpensiveCalculation
{
private double? cachedResult;
public double Result
{
get
{
if (cachedResult == null)
{
// 模拟耗时计算
cachedResult = Enumerable.Range(0, 1000000).Sum(i => Math.Sqrt(i));
}
return cachedResult.Value;
}
}
}
实际应用案例[编辑 | 编辑源代码]
用户界面数据绑定[编辑 | 编辑源代码]
在WPF或MAUI等框架中,计算属性常用于数据绑定:
public class PersonViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName => $"{FirstName} {LastName}";
}
业务规则封装[编辑 | 编辑源代码]
计算属性可以封装复杂的业务规则:
public class Order
{
public DateTime OrderDate { get; set; }
public decimal Amount { get; set; }
public bool IsEligibleForDiscount
{
get
{
return OrderDate.DayOfWeek == DayOfWeek.Monday &&
Amount > 1000;
}
}
}
表达式体属性[编辑 | 编辑源代码]
C# 6.0引入了表达式体属性,简化了只读计算属性的语法:
public class Circle
{
public double Radius { get; set; }
// 表达式体属性
public double Area => Math.PI * Radius * Radius;
}
与方法的比较[编辑 | 编辑源代码]
计算属性与方法的选择指南:
场景 | 使用属性 | 使用方法 |
---|---|---|
简单计算 | ✔️ | ❌ |
耗时操作 | ❌ | ✔️ |
有副作用 | ❌ | ✔️ |
需要参数 | ❌ | ✔️ |
最佳实践[编辑 | 编辑源代码]
1. 计算属性应该是幂等的(多次调用产生相同结果) 2. 避免在计算属性中执行耗时操作 3. 考虑线程安全性(特别是在缓存实现中) 4. 遵循.NET命名约定,使用PascalCase命名属性 5. 当计算逻辑复杂时,考虑使用方法替代
常见错误[编辑 | 编辑源代码]
无限递归[编辑 | 编辑源代码]
错误示例:
public class BadExample
{
private string name;
public string Name
{
get => Name; // 错误:无限递归
set => Name = value; // 错误:无限递归
}
}
正确写法:
public class GoodExample
{
private string name;
public string Name
{
get => name;
set => name = value;
}
}
忽略性能影响[编辑 | 编辑源代码]
避免在频繁调用的属性中进行昂贵计算:
// 不佳的实现
public double ExpensiveValue
{
get
{
// 每次访问都执行数据库查询
return Database.QueryExpensiveValue();
}
}
总结[编辑 | 编辑源代码]
计算属性是C#中强大的特性,它:
- 提供简洁的语法封装计算逻辑
- 增强代码可读性和维护性
- 支持数据绑定等高级场景
- 遵循面向对象封装原则
合理使用计算属性可以显著提高代码质量,但需要注意性能影响和正确实现。