Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Lazy<T> get around needing new() constraint?

Example 1 (does not compile):

void Main()
{
    var c = new C<D>();
    c.M.F();
}

class C<T>
{
    T _m = null;
    public T M { get {
        if(_m == null) _m = new T();
        return _m; 
    } }
}

class D
{
    public void F() { Console.WriteLine ("i was created"); }
}

Result:

Cannot create an instance of the variable type 'T' because it does not have the new() constraint

Example 2 (works):

void Main()
{
    var c = new C<D>();
    c.M.F();
}

class C<T>
{
    Lazy<T> _m = new Lazy<T>();
    public T M { get { return _m.Value; } }
}

class D
{
    public void F() { Console.WriteLine ("i was created"); }
}

Result:

i was created
like image 335
Aaron Anodide Avatar asked Nov 15 '11 01:11

Aaron Anodide


People also ask

How does Lazy t work?

The Lazy<T> object ensures that all threads use the same instance of the lazily initialized object and discards the instances that are not used. Thus, the cost of reducing the locking overhead is that your program might sometimes create and discard extra copies of an expensive object.

Is Lazy t thread-safe?

By default, Lazy<T> objects are thread-safe. That is, if the constructor does not specify the kind of thread safety, the Lazy<T> objects it creates are thread-safe.

How to use Lazy t in c#?

Remarks. Use lazy initialization to defer the creation of a large or resource-intensive object, or the execution of a resource-intensive task, particularly when such creation or execution might not occur during the lifetime of the program. To prepare for lazy initialization, you create an instance of Lazy<T>.


1 Answers

If you delve into the source code, you'll see that Lazy<T> ultimately uses Activator:

return new Lazy<T>.Boxed((T)Activator.CreateInstance(typeof(T)));

This is just a shortcut for using reflection. Since it's not instantiating the type via the actual generic type argument (new T()) but rather invoking the constructor through reflection, no where T : new() constraint is needed.

like image 187
Kirk Woll Avatar answered Sep 20 '22 18:09

Kirk Woll