C# 加载属性延迟加载

C# 加载属性延迟加载,c#,vb.net,design-patterns,lazy-evaluation,C#,Vb.net,Design Patterns,Lazy Evaluation,我有一个属性,getter应该只在第一次加载它的值。第二次返回加载的值而不再次加载时: private Object\u MemberValue; 公共对象成员值 { 得到 { 如果(_MemberValue==null) { _MemberValue=LoadMember(); } 返回_MemberValue; } } 在VB.NET中有Static关键字。使用它,您不必声明类范围的成员 公共属性MemberValue作为对象 得到 作为对象的静态值=无 如果(值为零),则 value=L

我有一个属性,getter应该只在第一次加载它的值。第二次返回加载的值而不再次加载时:

private Object\u MemberValue;
公共对象成员值
{
得到
{
如果(_MemberValue==null)
{
_MemberValue=LoadMember();
}
返回_MemberValue;
}
}
在VB.NET中有
Static
关键字。使用它,您不必声明类范围的成员

公共属性MemberValue作为对象
得到
作为对象的静态值=无
如果(值为零),则
value=LoadMember()
如果结束
返回值
结束
端属性
在C#中没有这样的关键字


是否有更好的C#实现这个问题或其他模式?

您最初的方法似乎很合适,我从来没有理由做一些不同的事情。也就是说,如果您的目标是避免可能写入getter外部的类级字段,那么类似的方法可能会奏效。还有许多其他的只读、写、SetOnce实现也可以类似地工作

ReadOnlyField.cs

public class ReadOnlyField<T>
{
    private bool _frozen;
    private T _value;

    public T Value
    {
        get { return _value; }
        set
        { 
            if (_frozen)
                throw new InvalidOperationException();

            _value = value;
        }
    }

    public void Freeze()
    {
        _frozen = true;
    }
}
public class YourObject
{
    private readonly ReadOnlyField<object> _someMember;

    public object MemberValue
    {
        get
        {
            if(_someMember.Value == null)
            {
                _someMember.Value = LoadMember();
                _someMember.Freeze();
            }

            return _someMember.Value;
        }
    }

    public YourObject()
    {
        _someMember = new ReadOnlyField<object>();
    }
}
公共类只读字段
{
私人银行冻结;
私人T_值;
公共价值
{
获取{返回_值;}
设置
{ 
如果(_冻结)
抛出新的InvalidOperationException();
_价值=价值;
}
}
公众假期冻结
{
_冻结=真实;
}
}
YourObject.cs

public class ReadOnlyField<T>
{
    private bool _frozen;
    private T _value;

    public T Value
    {
        get { return _value; }
        set
        { 
            if (_frozen)
                throw new InvalidOperationException();

            _value = value;
        }
    }

    public void Freeze()
    {
        _frozen = true;
    }
}
public class YourObject
{
    private readonly ReadOnlyField<object> _someMember;

    public object MemberValue
    {
        get
        {
            if(_someMember.Value == null)
            {
                _someMember.Value = LoadMember();
                _someMember.Freeze();
            }

            return _someMember.Value;
        }
    }

    public YourObject()
    {
        _someMember = new ReadOnlyField<object>();
    }
}
public类对象
{
私有只读只读字段_someMember;
公共对象成员值
{
得到
{
if(_someMember.Value==null)
{
_Value=LoadMember();
_someMember.Freeze();
}
返回_someMember.Value;
}
}
公共对象()
{
_someMember=newreadonlyfield();
}
}
这并不完美。与VB.Net示例不同;getter之外的代码可以先写入字段,但至少在调用Freeze后可以防止它被覆盖

这个问题或其他模式有更好的C#实现吗

可能不会。如果愿意,可以使用
Lazy
作为替代,但基本上与第一个示例相同。在VB.NET中使用
Static
,因此我不会以任何方式使用它

如果您更喜欢
Lazy
,我会使用以下方法:

private Lazy<object> _MemberLazy = new Lazy<object>(LoadMember);

public object MemberValue
{
    get
    {
        return _MemberLazy.Value;
    }
}
private Lazy\u MemberLazy=new Lazy(LoadMember);
公共对象成员值
{
得到
{
返回_MemberLazy.Value;
}
}

查看Lazy对象顺便说一句,您的第一个代码段有什么问题?@patrickhoffman没有错,但感觉有更好的实现来解决这个问题。关于使用
Lazy
类的相关问题。啊,好吧,我想我应该得到否决票,因为我试图帮助你们消除对VB.NET的
Static
的误解……有人在这个问题上大做文章。显然不喜欢这个问题或答案+我把这个标记为答案,因为它回答了我的具体问题。我没有投票,但我认为这是因为你似乎在重复Lazy从.NET开始做的事情4@the_lotus懒惰有它自己的局限性。这个问题不清楚,也不现实。加载可能是其他变量的函数,您可能需要从UI或其他事件刷新。。