philpenn

Lazy<T> Optimized Resource Initialization

Download this episode

Download Video

Description

Join Josh and Steve as they demonstrate how to use the new .NET4 Lazy<T> class in optimized object initialization scenarios.

Lazy<T> is one of many new thread-safe data-structures available with .NET4 and Visual Studio 2010.

Learn more about the System.Collections.Concurrent namespace and keep abreast of Parallel Computing tools and techniques via the Concurrency Dev Center.

See all videos in this series.

Embed

Format

Available formats for this video:

Actual format may change based on video formats available and browser capability.

    The Discussion

    • exoteric

      This looks like the "once" construct in Eiffel coupled with locking code for thread-safety.

       

      It would be somewhat interesting to be able to do something like this

       

      [Lazy] public int Expensive { get { return InsanelyExpensive(); } }

       

      where the compiler will use the attribute to modify the code to use Lazy<int> underneath. This will make the laziness completely transparent to the caller, the transformed code will be something like this

       

       public class LazyOrNot { private static T Slow<T>(T x) // why does this need to be static? { System.Threading.Thread.Sleep(3000); return x; } public int LetsPlay1 { get { return Slow(42); } } private Lazy<int> lazy = new Lazy<int>(()
       => Slow(42)); public int LetsPlay2 { get { return lazy.Value; } } [Lazy] public int LetsPlay3 { get { return LetsPlay1; } } } 

       

      Many interesting things possible...

       

      Actually, I wonder if Lazy is the right name, given that a method is also "lazy" until evaluated but it does not memoize its result which is what this construct does I presume: evaluate once and remember, just like the Eiffel "once" (maybe Memo<T>; but Lazy<T> is more easily understood, probably)

    • ramooon

      What's the hype with the "lazy" word ?

      Why not use "Cached" so everybody would understand it ?

       

      Exoteric: why not as a keyword ?

      public lazy int Expensive { get; }

      public lazy int SomeMethod() { ... }   // so it's only called once

    • ramooon

      Is there a way to invalidate the "cached" value ?

      What happen when we use it with a deferred LINQ query ?

    • pencilman

      I think this is great

      thanks,

      Pencils

    • phillips.​josh

      How I love our developer community. Smiley

       

      You're right on the money -- lazy language integration would be sweet, so sweet in fact, that F# has it. Smiley  As for C#, it's certainly something that the C# team has and would considered but it takes a lot of effort and a lot of vetting to get a new feature into a language.  The type hasn't even been RTMed yet!  That said, the C# team always loves feedback and feature requests:

       

      Go to https://connect.microsoft.com/VisualStudio?wa=wsignin1.0, click "Submit Feedback for VS2010, then click "Submit a Suggestion"

       

      Josh

    • phillips.​josh

      ramoon,

       

      Lazy is a pretty well-known CS concept and "Cached" doesn't seem to capture the most important function of the type -- you can have something that's eagerly evaluated and cached as well. 

       

      There is no way to invalidate a specific Lazy<T> instance.  We wanted Lazy<T> to be as observationally pure as possible and behave just as if it were any other variable.  For example, in C#, if you can't create an int of 4 and then invalidate it -- you simply reassign it.  The same goes for a Lazy<int>. 

       

      As for LINQ query, I'm not sure I understand the question.. When you use a Lazy<T> in a LINQ or PLINQ query, it will be evaluated whenever the execution occurs Value is called.

       

      Hope that helps!

       

      Josh

    • exoteric

      Actually, not having implemented attributes myself, I assumed that you could create a C# attribute and setup a code transformation "pipeline" (chained attributes?) to transform the source code into something where the function is memoized, but I guess this is something the C# team is investigating. I'd rather have that than another keyword.

       

      It reminds me of D where you can do compile-time function execution and string manipulation (actually you could build a compile-time parser that builds an AST, does code-transformation and outputs the transformed source code, all at compile-time). C# would hopefully let you do that directly. Well, it's not *that* important, just interesting.

       

      This Lazy type is very nice and I'll probably be using it here and there. In a similar fashion I made the Unnullable type but I think it would be cool if somehow these types could cloak themselves as their nested types so you didn't "see" them - but that would require compiler support as above.

    • zurk

      Whoa! We'll be able to clean up a lot of our code.  We currently have that pattern all over the place.

    • aL_

      so, in MEF there is a Lazy<T,TMetadata> will that go into the bcl as well?

       

      also, it would really be helpful to have implicit operators between Lazy<T> and T Smiley

    • phillips.​josh

      Hi aL_,

       

      Lazy<T,TMetadata> actually extends Lazy<T> and no it won't end up in BCL, for Beta 2, it's actually in System.ComponentModel.Composition.  We'd considered the implicit cast operator but because we're executing arbitrary code we determined that's a bad idea.  It's only complicated by the fact that the valueFactory delegate may thrown an exception.

       

      Thanks for the feedback!

       

      Josh

    Comments closed

    Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation, please create a new thread in our Forums, or Contact Us and let us know.