With the feedback that (my brain) could understand I've came to this for now.
- (I think) I literally copied the locking structure of Lazy, thread-safe Singleton
- Included adding the volatile keyword for the _Loaded check
- Moved the generic definition to the class type. Adding a bit more boilerplate code on the advantage of more type safety and no-boxing
- Added a warning to remind myself there might be issues
As for the advice "Leave it to the smarter people". That's something I can't work with. I like to learn, I like other people to learn and I prefer a society where people are motivated to fail (against calculated cost) to learn for themselves.
I appreciate that everyone has a different opinion about that, that's okay.
I still not 100% sure if this solves at least the thread-safety problems of the first version, because the conversation went a bit off-topic imo. If anyone that is knowledgable can comment on that I would appreciate it. For the rest; I'm going to try to use this code and see what it does in production and if it causes (practical) problems for my caching of properties.
/// <summary>
/// Warning: might not be as performant (and safe?) as the Lazy<T>, see:
/// https://codereview.stackexchange.com/questions/207708/own-implementation-of-lazyt-object
/// </summary>
public class MyLazy<T>
{
private T _Value;
private volatile bool _Loaded;
private object _Lock = new object();
public T Get(Func<T> create)
{
if ( !_Loaded )
{
lock (_Lock)
{
if ( !_Loaded ) // double checked lock
{
_Value = create();
_Loaded = true;
}
}
}
return _Value;
}
public void Invalidate()
{
lock ( _Lock )
_Loaded = false;
}
}