c#属性封装

本文关键字:封装 属性 | 更新日期: 2023-09-27 18:08:45

c#属性是我在C家族语言中发现的最有表现力的工具之一。我的问题是为什么"后台"字段不能在属性块内?这是什么理由不允许的?

public int Salary //Compile error
{
    int salary = 1000;
    get {} //custom use of salary
    set {} 
}

我发现做下面的事情相当笨拙

int salary = 1000; //poor encapsulation but working code
public int Salary
{
    get {} //edit the private field salary
    set {} 
}

我通过使用以下模式记忆属性对一些代码进行了一些优化

int field;
bool flag = false;
public int Field 
{
    get
    {
        if (flag)
            return field;
        flag = true;
        return field = expensiveOperation();
    }
}

我真的很想把这些变量移到属性的作用域中,因为它们没有理由在实例

的作用域中
public int Field //compile error
{
    int field;
    bool flag = false;
    get
    {
        if (flag)
            return field;
        flag = true;
        return field = expensiveOperation();
    }
}

c#属性封装

如果你有属性,它的工作与自己的数据,不相关的对象属性所在,那么我认为你应该从你的类提取该属性。属性的目的是处理与声明属性的类相关的数据,并具有整个类的作用域。

还要记住-属性只是一对方法的语法糖。


旁注:您可以使用Lazy<T>延迟初始化字段。例如

Lazy<int> field = new Lazy<int>(() => expensiveOperation());

我认为在属性范围内声明字段只有在该范围定义了字段的生命周期时才有意义。但事实并非如此。该字段属于该类,只要该类的实例存在(例如实例字段),该字段就存在。

至于延迟初始化模式,请查看lazy类。它很好地封装了昂贵的初始化,还提供了线程安全性。