加载 属性 延迟加载
Load property lazy loading
我有一个 属性,getter 应该只在第一次加载它的值。第二次它 returns 加载值而不再次加载它:
private Object _MemberValue;
public Object MemberValue
{
get
{
if(_MemberValue == null)
{
_MemberValue = LoadMember();
}
return _MemberValue;
}
}
在 VB.NET 中有 Static
关键字。有了它,您不必声明 class 宽成员。
Public Property MemberValue as Object
Get
Static value as Object = Nothing
If (value is Nothing) Then
value = LoadMember()
End If
Return value
End Get
End Property
在 C# 中没有这样的关键字。
这个问题或其他模式是否有更好的 C# 实现?
你最初的做法似乎很合适,我从来没有理由做不同的事情。也就是说,如果您的目标是避免可能写入 getter 之外的 class 级别字段,那么 this 之类的内容可能会起作用。还有许多其他 ReadOnly、WriteOnce、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;
}
}
YourObject.cs
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>();
}
}
它并不完美。与您的 VB.Net 示例不同; getter 之外的代码可以先写入该字段,但至少在调用 Freeze 后您不会被覆盖。
Are there better C# implementations of this problem or other patterns?
可能不会。如果愿意,您可以使用 Lazy<T>
作为替代,但基本上它与您的第一个示例相同。在 VB.NET has some serious drawbacks 中使用 Static
,所以我不会以任何方式使用它。
如果您更喜欢Lazy<T>
,这就是我要使用的:
private Lazy<object> _MemberLazy = new Lazy<object>(LoadMember);
public object MemberValue
{
get
{
return _MemberLazy.Value;
}
}
我有一个 属性,getter 应该只在第一次加载它的值。第二次它 returns 加载值而不再次加载它:
private Object _MemberValue;
public Object MemberValue
{
get
{
if(_MemberValue == null)
{
_MemberValue = LoadMember();
}
return _MemberValue;
}
}
在 VB.NET 中有 Static
关键字。有了它,您不必声明 class 宽成员。
Public Property MemberValue as Object
Get
Static value as Object = Nothing
If (value is Nothing) Then
value = LoadMember()
End If
Return value
End Get
End Property
在 C# 中没有这样的关键字。
这个问题或其他模式是否有更好的 C# 实现?
你最初的做法似乎很合适,我从来没有理由做不同的事情。也就是说,如果您的目标是避免可能写入 getter 之外的 class 级别字段,那么 this 之类的内容可能会起作用。还有许多其他 ReadOnly、WriteOnce、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;
}
}
YourObject.cs
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>();
}
}
它并不完美。与您的 VB.Net 示例不同; getter 之外的代码可以先写入该字段,但至少在调用 Freeze 后您不会被覆盖。
Are there better C# implementations of this problem or other patterns?
可能不会。如果愿意,您可以使用 Lazy<T>
作为替代,但基本上它与您的第一个示例相同。在 VB.NET has some serious drawbacks 中使用 Static
,所以我不会以任何方式使用它。
如果您更喜欢Lazy<T>
,这就是我要使用的:
private Lazy<object> _MemberLazy = new Lazy<object>(LoadMember);
public object MemberValue
{
get
{
return _MemberLazy.Value;
}
}