C#属性与索引器使用


属性(Properties)

属性是C#中一种特殊的成员,它提供了对类或对象字段的灵活访问机制。属性结合了字段和方法的特性,允许你在访问数据时添加逻辑验证。

属性的基本语法

public class Person
{
    private string _name; // 私有字段

    // 属性
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
}

自动实现属性

C#提供了简化的属性声明方式:

public class Person
{
    public string Name { get; set; } // 自动实现属性
}

编译器会自动为这种属性生成一个私有字段和基本的get/set方法。

只读属性

public class Circle
{
    public double Radius { get; } // 只读属性

    public Circle(double radius)
    {
        Radius = radius;
    }
}

属性验证

可以在set访问器中添加验证逻辑:

public class Person
{
    private int _age;

    public int Age
    {
        get => _age;
        set
        {
            if (value < 0 || value > 120)
                throw new ArgumentOutOfRangeException("Age must be between 0 and 120");
            _age = value;
        }
    }
}

表达式体属性

C# 6.0引入了表达式体属性:

public class Rectangle
{
    public double Width { get; set; }
    public double Height { get; set; }

    public double Area => Width * Height; // 表达式体属性
}

索引器(Indexers)

索引器允许类或结构的实例像数组一样被索引。当您为类定义索引器时,该类的行为类似于虚拟数组。

基本索引器语法

public class StringCollection
{
    private string[] _strings = new string[10];

    // 索引器
    public string this[int index]
    {
        get => _strings[index];
        set => _strings[index] = value;
    }
}

使用示例:

var collection = new StringCollection();
collection[0] = "Hello"; // 使用索引器设置值
Console.WriteLine(collection[0]); // 使用索引器获取值

多参数索引器

索引器可以有多个参数:

public class Matrix
{
    private double[,] _data = new double[10, 10];

    public double this[int row, int column]
    {
        get => _data[row, column];
        set => _data[row, column] = value;
    }
}

使用示例:

var matrix = new Matrix();
matrix[0, 0] = 1.0;
Console.WriteLine(matrix[0, 0]);

字符串索引器

索引器不仅限于整数参数:

public class Dictionary
{
    private Dictionary<string, string> _dictionary = new Dictionary<string, string>();

    public string this[string key]
    {
        get => _dictionary[key];
        set => _dictionary[key] = value;
    }
}

表达式体索引器

C# 7.0开始支持表达式体索引器:

public class SampleCollection
{
    private string[] arr = new string[100];

    public string this[int i]
    {
        get => arr[i];
        set => arr[i] = value;
    }
}

属性和索引器的比较

特性属性索引器
访问方式通过名称访问通过索引访问
参数无参数可以有一个或多个参数
重载不能重载可以重载
用途访问单个数据成员访问集合中的元素
语法public int Prop { get; set; }public int this[int index] { get; set; }

实际应用示例

public class ShoppingCart
{
    private List<Product> _products = new List<Product>();

    // 只读属性,返回购物车中商品数量
    public int ItemCount => _products.Count;

    // 只读属性,计算总价
    public decimal TotalPrice => _products.Sum(p => p.Price * p.Quantity);

    // 索引器,通过产品ID访问
    public Product this[int productId]
    {
        get => _products.FirstOrDefault(p => p.Id == productId);
    }

    // 索引器,通过产品名称访问
    public Product this[string productName]
    {
        get => _products.FirstOrDefault(p => p.Name == productName);
    }

    public void AddProduct(Product product)
    {
        var existing = _products.FirstOrDefault(p => p.Id == product.Id);
        if (existing != null)
            existing.Quantity += product.Quantity;
        else
            _products.Add(product);
    }
}

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public int Quantity { get; set; }
}

总结

  • 属性提供了一种安全、灵活的方式来访问类的字段,可以在访问时添加验证逻辑
  • 索引器让类的实例可以像数组或集合一样被索引访问
  • 两者都可以使用表达式体语法简化代码
  • 索引器支持重载,可以根据不同的参数类型提供不同的访问方式
  • 合理使用属性和索引器可以提高代码的可读性和安全性

属性和索引器是C#中强大的特性,它们使你的类更加直观易用,同时保持了良好的封装性。在设计类时,考虑使用这些特性来提供更优雅的API。


发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注