为了延迟访问,您如何在本地封装字段值?

时间:2012-09-07 22:09:49

标签: c# inheritance properties encapsulation

以下片段展示了我最近遇到的一个问题。

基本上我想知道隐藏属性的支持值是否比使用继承更好的解决方案。

作为一个附带问题,我的非编译解决方案隐含的功能是否可能对未来版本的C#有用?

// This is a service that supplies a value but doesn't want to be called 
// until needed.
static class Service
{
    public static int GetP()
    {
        Console.WriteLine ("doing work...");
        return 1;
    }
}

// This is a class that implements a property which calls the service
// the first time that property is accessed but nothing stops the
// same code from accidentally referencing the uninitialized backing value.
class C
{
    void F()
    {
        // Easy to accidentally reference backing value of property
        Console.WriteLine (this.p);
    }

    int p = 0;
    int P
    {
        get
        {
            if(p == 0)
                p = Service.GetP();
            return p;
        }
    }
}

使用带有私有后备值的继承和受保护属性的解决方案。

// This class hides the backing value and exposed the property the derived class.
class CBase
{
    int p = 0;
    protected int P
    {
        get
        {
            if(p == 0)
                p = Service.GetP();
            return p;
        }
    }
}

class C1 : CBase
{
    void F()
    {
        // Now I can't see the backing value but I've used inheritance for the sole purpose of hiding it
        Console.WriteLine (this.P);
    }
}

如果const可以在实例级方法/属性的主体中延迟设置直到第一次运行时使用呢?

class D
{
    int P
    {
        get
        {
            const int a = Service.GetP(); // Doesn't compile
            return a;
        }
    }
}

1 个答案:

答案 0 :(得分:3)

如果您使用的是.net 4,请使用Lazy

class C
{
    private Lazy<int> p = new Lazy<int>(() => Service.GetP());

    private int P
    {
        get
        {
            return p.Value;
        }
    }
}

第一次访问Lazy.Value时,将调用提供给构造函数的函数来初始化该值。