Free mag vol1 | Page 556

CHAPTER 13  UNDERSTANDING OBJECT LIFETIME private AllTracks allSongs = new AllTracks(); } public AllTracks GetAllTracks() { // Return all of the songs. return allSongs; } The current implementation of MediaPlayer makes the assumption that the object user will want to obtain a list of songs via the GetAllTracks() method. Well, what if the object user does not need to obtain this list? In our current implementation, the AllTracks member variable will still be allocated, thereby creating 10,000 Song objects in memory, as follows: static void Main(string[] args) { Console.WriteLine("***** Fun with Lazy Instantiation *****\n"); // This caller does not care about getting all songs, // but indirectly created 10,000 objects! MediaPlayer myPlayer = new MediaPlayer(); myPlayer.Play(); } Console.ReadLine(); Clearly, you would rather not create 10,000 objects that nobody will use, as that will add a good deal of stress to the .NET garbage collector. While you could manually add some code to ensure the allSongs object is created only if used (perhaps using the factory method design pattern), there is an easier way. The base class libraries provide a very useful generic class named Lazy<>, defined in the System namespace of mscorlib.dll. This class allows you to define data that will not be created unless your code base actually makes use of it. As this is a generic class, you must specify the type of item to be created on first use, which can be any type with the .NET base class libraries or a custom type you have authored yourself. To enable lazy instantiation of the AllTracks member variable, you can simply replace this: // The MediaPlayer has-an AllTracks object. class MediaPlayer { ... private AllTracks allSongs = new AllTracks(); } public AllTracks GetAllTracks() { // Return all of the songs. return allSongs; } with this: // The MediaPlayer has-an Lazy object. class MediaPlayer { ... 497