#1,189 – Lambda Expression Can Capture Static Data

A lambda expression set within a static method can make use of a class’ static data.  If the static data changes after the lambda is defined, invoking the lambda later will reflect the new (modified) static data.

Suppose that we have a Dog.SetStaticLambda method that defines a lambda using some static data:

    public class Dog
    {
        public string Name { get; set; }

        public Dog(string name)
        {
            Name = name;
        }

        public static string DogMotto;

        private static Action myStaticLambda;

        public static void SetStaticLambda()
        {
            myStaticLambda = () => Console.WriteLine("Motto: {0}", DogMotto);
        }

        public static void InvokeStaticLambda()
        {
            myStaticLambda();
        }
    }

Below, we make use of these methods. Note that if we invoke the lambda after changing the static data, the new data is used.

            Dog.DogMotto = "Serving mankind for generations";
            Dog.SetStaticLambda();
            Dog.InvokeStaticLambda();  // Serving..

            Dog.DogMotto = "We want more treats";
            Dog.InvokeStaticLambda();  // Want more..

1189-001

Advertisement

#1,044 – How Static Data Behaves in Generic Types

There is only a single copy of each static data item, rather than one copy for each instance of the class.

When you have a static data item in a generic class, there is a single copy of that data item for each constructed type based on the generic type.  A constructed type is a type declaration that is based on a generic type, providing arguments for the generic type’s type parameters.

Assume that we define a PileOf<T> type that has a static NumInAllPiles field, incremented as part of an Add method.  We reference the static field using the constructed class name and see that each constructed type has its own copy of the static data.

            // Pile of 1 dog
            PileOf<Dog> pile1 = new PileOf<Dog>();
            pile1.Add(new Dog("Bowser"));

            // Pile of 2 dogs
            PileOf<Dog> pile2 = new PileOf<Dog>();
            pile2.Add(new Dog("Kirby"));
            pile2.Add(new Dog("Fido"));

            // Pile of 1 cat
            PileOf<Cat> pile3 = new PileOf<Cat>();
            pile3.Add(new Cat("Fluffy"));

            Console.WriteLine(PileOf<Dog>.NumInAllPiles);  // 3
            Console.WriteLine(PileOf<Cat>.NumInAllPiles);  // 1

#608 – Instance Methods Can Use Static Data

Instance methods in a class can make use of any of the public or private static data that belongs to that class.  (They can also make use of static data from other classes, provided that it is accessible).

    public class Dog
    {
        // Instance Properties
        public string Name { get; set; }
        public int Age { get; set; }

        // Static property
        public static Dog LastGuyThatBarked { get; protected set; }

        // Public static data
        public readonly static string TheDogMotto = "Man's Best Friend";

        // Private static data
        private static int TotalNumDogs = 0;

        public Dog(string name, int age)
        {
            Name = name;
            Age = age;
            TotalNumDogs++;
        }

        public void Bark()
        {
            Console.WriteLine("{0} says Woof", Name);

            // Access static property
            Dog.LastGuyThatBarked = this;

            // Access static data
            Console.WriteLine("There are {0} total dogs", Dog.TotalNumDogs);
            Console.WriteLine("Remember our motto: {0}", Dog.TheDogMotto);
        }
    }

#292 – A Static Constructor Initializes Static Data

In the same way that you can define instance constructors to initialize instance data in a class, you can define a static constructor to initialize any static data in the class.

A static constructor is defined using the static keyword and the name of the class.  The constructor takes no arguments and you can only define one static constructor.  You do not declare a static constructor as either public or private.

        public static string Motto { get; set; }
        public static int NumDogs { get; private set; }

        static Dog()
        {
            Motto = "We're like wolves.  Only friendlier.";
            NumDogs = 0;
        }

You cannot dictate when a static constructor will be called and you can’t call it directly.  The compiler guarantees that it will be called automatically before you create any instances of your class or access any static data.

#283 – Instance Methods Can Call Static Methods

Instance methods in a class can access static data or call static methods.  The instance method accesses static data or methods in the same way that other code does–by using the class name to qualify the data or method name.

Here’s an example, where the Dog.Bark instance method makes use of the private static Dog.FormatTheCreed method:

        // Static property -- one value for all dogs
        public static string Creed { get; set; }

        // Private static method to format our Dog creed
        private static string FormatTheCreed()
        {
            return string.Format("As dogs, we believe: {0}", Dog.Creed);
        }

        // Instance method, in which a Dog barks
        public void Bark()
        {
            // Dump out my name and the universal Dog creed.
            Console.WriteLine("{0}: 'Woof'!  (Creed: [{1}])", this.Name, Dog.FormatTheCreed());
        }

Calling the Bark method:

            // Set static property
            Dog.Creed = "We serve man";

            Dog kirby = new Dog("Kirby");
            kirby.Bark();

#281 – Declaring and Using Static Methods in a Class

A static method in a class is similar to an instance method, except that it acts upon the class’ static data–fields and properties–rather than on the instance data stored with a single instance of the class.

There is only one copy of each static data item, no matter how many instances of the class exist.

Here’s an example of defining a static method in a class.

        // Static property -- one value for all dogs
        public static string Creed { get; set; }

        // Static method acts on static data
        public static void RepeatYourCreed(int numRepeats)
        {
            for (int i = 0; i < numRepeats; i++)
                Console.WriteLine("My creed is: {0}", Creed);
        }

To call a static method, you just prefix the method with the name of the class (rather than with a reference to an instance of the class).

            // Set static property
            Dog.Creed = "We serve man";

            // Call static method
            Dog.RepeatYourCreed(3);

#46 – There Is Only One Copy of Static Data

With instance data members of a class, there is a unique set of data that exists for each instance of the class that you create.  However, for static data members, there is always just one copy of the static data for that class.  Since the data is associated with no particular instance of the class, all references to that static data work with the same copy.

 // Create two new Person objects--two sets of instance data.
 Person p1 = new Person("Sean", 46);
 Person p2 = new Person("Fred", 28);

 // Change static data--one copy for entire Person class
 Person.Motto = "It's good to be human";