#1, 023 – Fields Are Initialized Before Execution of Constructors

When you declare a field in a class and initialize the field when it is declared, the initialization of the field will happen when an instance of the class is created, but before the constructor is invoked.  All fields are initialized before the constructor executes, in the order in which they are declared.

Assume that we have a Dog class defined as follows:

    public class Dog
    {
        public string Sound = "Woof";
        public Cat Friend = new Cat("Garfield");
        public string Name { get; set; }

        public Dog(string name)
        {
            Console.WriteLine("Dog constructor for {0}, Sound is {1}", name, Sound);
            Name = name;
        }
    }

When we create an instance of a Dog, the Sound and Friend fields are initialized before the Dog constructor is invoked.

            Dog d = new Dog("Kirby");

1023-001

Advertisements

#791 – Properties Are Not Variables

A property cannot be used in the same way as a variable, like a field can.

A field is a variable that is defined within a class and it denotes an actual storage location.  Because it refers to a storage location, you can pass a field by reference, using a ref or out keyword on the argument.

If Name is a public field of a Dog class, you can do this:

        static void Main(string[] args)
        {
            Dog d = new Dog("Bob");

            MakeNoble(ref d.Name);
        }

        private static void MakeNoble(ref string name)
        {
            name = "Sir " + name;
        }

A property, on the other hand, is not a variable and its name does not refer directly to a storage location.  So you can’t pass a property as a ref or out argument to a method.

            Dog d = new Dog("Bob");
            d.Age = 5;
            AgeMe(ref d.Age);  // Compile-time Error

#788 – A Backing Field Stores Data for a Property

When you create a property, you’re creating a set of accessor methods to read and write the property’s value.  You also typically need a place to store the actual property value.

The data member where the property’s value is actually stored is known as a backing field, typically defined as a private field.

When you create an auto-implemented property, you don’t explicitly declare a backing field, but the compiler creates one for you in the IL that is generated.  Your code doesn’t have access to the field.

        // Backing field not declared, created automatically
        public int Age { get; set; }

If you create the property explicitly, then you’ll declare the backing field yourself.

        // Backing field
        private int age;

        // Property
        public int Age
        {
            get { return age; }
            set
            {
                if (value != age)
                    age = value;
            }
        }

#787 – Avoid Public Fields in a Class

When you declare a field in a class, you can set its accessibility to: public, private, protected, internal, or protected internal.

In general, you should declare fields as private or protected, instead of making them public.  For purposes of encapsulation, you typically expose public data members as properties, rather than fields.  This hides the implementation details of the data item from users of the class and makes it easier to change those details without changing or affecting code that uses the class.

Instead of this:

public class Dog
{
    // A field
    public string Name;
}

You should do this:

    public class Dog
    {
        // A property
        public string Name { get; set; }
    }

Or this:

        private string name;
        public string Name
        {
            get { return name; }
            set
            {
                // do other stuff
                name = value;
            }
        }

#669 – Initializing Fields by Calling A Method

You can initialize fields in a class at the point where you declare them, using a constant.  You can also initialize a field to a value returned from a call to a method–as long as the method is not an instance method within the same class.

Here’s an example, where we call a static method in the same class to initialize a field.

    public class Dog
    {
        private static string GenerateCreationInfo()
        {
            return string.Format("I was created at {0}", DateTime.Now);
        }

        public string CreationInfo = GenerateCreationInfo();

        public string Name { get; set; }
        public int Age { get; set; }

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

#602 – Initializing Fields in a Class

You can initialize instance-level fields in a class when you declare them.  If you do not initialize them, all fields are initialized to default values (0 for numeric types, null for reference types).

In the fragment of the Dog class below, we initialize two instance-level fields and one static field.

    public class Dog
    {
        // Instance fields
        public string Name = "Bowser";
        public int Age = 1;

        // Static fields (one for entire type, rather than 1/instance)
        public static string CanineMotto = "We're here to serve you";

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

        public Dog() { }
    }
            Dog myDog = new Dog();
            Console.WriteLine("My dog {0} is aged {1}", myDog.Name, myDog.Age);

            Dog yourDog = new Dog("Kirby", 15);
            Console.WriteLine("Your dog {0} is aged {1}", yourDog.Name, yourDog.Age);

            Console.WriteLine("Dog motto: {0}", Dog.CanineMotto);

#443 – An Interface Cannot Contain Fields

An interface can contain methods, properties, events or indexers.  It cannot contain fields.

    interface IMoo
    {
        // Methods
        void Moo();

        // Field not allowed - compile-time error
        string Name;

Instead of a field, you can use a property.

    interface IMoo
    {
        // Methods
        void Moo();

        // Name as a property is OK
        string Name { get; set; }

Interfaces don’t allow fields because they consist of a contract that is a list of methods, whose implementation is provided by a class. Properties are implemented as methods (get and set accessors), so they fit this model.  But fields are just data locations, so it doesn’t make sense to include them in an interface.