#695 – Static Methods Can Access Static Members

A static method can only access static members in the class that it’s defined in.

(If you pass an instance of an object to a static method, it can invoke instance members on that object).

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

        // Instance constructor
        public Dog(string name, int age)
        {
            Name = name;
            Age = age;
        }

        // Instance method
        public void Bark()
        {
            Console.WriteLine("{0} says WOOF", Name);
        }

        // Static property
        public static string DogMotto { get; protected set; }

        // Static constructor
        static Dog()
        {
            DogMotto = "Serve humans";
        }

        // Static method
        public static void AboutDogs()
        {
            // Accessing static data
            Console.WriteLine("Dogs believe: {0}", DogMotto);

            // ERROR: Can't access instance property
            Console.WriteLine(Name);

            // ERROR: Can't call instance method
            Bark();
        }
    }

Trying to access instance methods or data from a static member will generate a compile-time error.

#613 – Interfaces Cannot Contain Static Members

An interface is a list of methods, properties, events and indexers that a class may implement.  All methods, properties and events defined in the interface are implicitly instance members, rather than static members.

    public interface IDogStuff
    {
        bool CanBark { get; set; }
        void Bark();

        // Compile-time Error: The modifier 'static' is not valid for this item
        static string GenerateMotto();

    }

#387 – Static Events vs. Static Event Handler Methods

Events can be static events or instance events.  Static events are associated with the class as a whole, whereas instance events are associated with a specific instance of the class.

You can attach event handlers to both static and instance events.

            // Add handler to static event
            Dog.SomebodyBarked += new EventHandler<SomebodyBarkedEventArgs>(Dog_SomebodyBarked);

            Dog kirby = new Dog("Kirby");

            // Add handler to instance event
            kirby.Barked += new EventHandler<SomebodyBarkedEventArgs>(kirby_Barked);

In both cases, we’re attaching a handler that is a static method.

        static void Dog_SomebodyBarked(object sender, SomebodyBarkedEventArgs e)
        {
            Console.WriteLine("Dog {0} barked, saying {1}", e.DogName, e.Bark);
        }

We can also attach a handler that is an instance method.  So we can attach both static and instance methods as handlers, to either static or instance events.

For example:

            BarkLogger log = new BarkLogger();

            // Add instance method as handler for static event
            Dog.SomebodyBarked += new EventHandler<SomebodyBarkedEventArgs>(log.LogBark);

#318 – You Can’t Use the static Modifier On a Constant

Although constants can be treated as static member variables, you cannot include the static keyword when declaring a constant.  A constant is always effectively static, so the static keyword would be redundant.  The compiler will generate an error if you include it.

        // This is ok
        const string Demeanor = "friendly";

        // !! Compiler error - constant cannot be marked static
        static const int TheAnswer = 42;

#315 – Accessibility of Static Methods and Properties

Like instance methods and properties, you can define the accessibility of static methods and properties using access modifiers.  As with instance members, access modifiers on static members indicates what code has access to the member.

  • public – All code has access
  • private – Only code in the defining class has access
  • protected – Code in the defining class or derived classes has access
  • internal – All code in the defining assembly has access
  • protected internal – Code in the defining assembly or in derived classes has access
        // All code has access
        public static Dog MakeNewDog()
        {
        }

        // Only this class has access
        private static void InitSomeStaticData()
        {
        }

        // Subclass has access
        protected static void InitOtherStuff()
        {
        }

        // Code in same assembly has access
        internal static void RunSomeCalcs()
        {
        }

        // Code in same assembly or subclass has access
        protected internal static void DoOtherStuff()
        {
        }

#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);

#256 – Using Static Fields

Let’s say that we have both instance and static fields defined in a class:

        public string Name;

        public static string Creed;

This allows us read and write the Name property for each instance of the Dog class that we create.

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

            Dog jack = new Dog();
            jack.Name = "Jack";

Notice that each instance of a Dog has its own copy of the Name field, since Name is an instance field.

We can also read/write the static Creed field, using the class name to qualify the field, rather than an instance variable.

            Dog.Creed = "Man's best friend";

There is only one copy of the Creed field, since Creed is a static field.