#304 – Private Class Members

Class members marked with the accessibility keyword private are accessible only from code within the same class.

In the picture below, the Dog.DoBark method is marked as private.  Only the code in the blue block can call this method.

Advertisement

#303 – Accessibility of Class Members

Members of a class can have different kinds of accessibility.  An accessibility keyword indicates what source code can access the member.  The different types of accessibility are:

Accessibility Keyword Description
public All code can access the member
private Only other code in the class can access the member
protected Code in this class or any class that inherits from this class can access
internal Code in files in the same assembly (.dll or .exe) can access
protected internal Code in the same assembly or in classes that inherit from this class can access

Accessibility keywords can apply to the following kinds of members of a class: fields, properties, methods, constants, indexers, events, constructors and nested types.  They can apply to both instance and static members.

#302 – Generating an XML Documentation File

You can use XML Documentation in a class that you author, to provide documentation for the class and its members.

The compiler to generate a separate XML file containing all of your XML Documentation if you do the following:

  • Right-click your Project and select Properties
  • On the Build tab, check the XML documentation file option

If you open the XML file that is generated, you’ll see XML tags containing all of your XML Documentation.

You can use this XML file to automatically generate documentation for your class, with a custom tool or a tool like Sandcastle.

You can also distribute an XML documentation file, along with a binary DLL (e.g. class library).  If the XML documentation file is present, code that references the types in the DLL will be able to display the Intellisense for the types in the DLL.

#301 – Using XML Documentation at the Class Level

In addition to adding context to Intellisense for method calls, XML Documentation can be used to provide Intellisense context for a class itself.

You add XML Documentation to a class by entering “///” on a blank line immediately preceding the class keyword.  Visual Studio will create an empty template for you to fill in.

    /// <summary>
    ///
    /// </summary>
    public class Dog
    {

To finish the documentation, enter a short description of the purpose of the class, within the <summary> tags.

    /// <summary>
    /// Represents a Dog, one of our furry friends.  Dogs can
    /// bark and do basic chores like fetching your newspaper.
    /// </summary>
    public class Dog
    {

If a class has XML Documentation at the class level, Intellisense will display that information when you enter the name of the class in your code.

#300 – Use XML Documentation to Inform Intellisense

Intellisense in Visual Studio 2010 is a very powerful tool.  Among other things, it gives someone coding against a class additional information about a particular method and its parameters.

In the example below, we’ve just typed the opening parenthesis after the name of the Bark method.  An Intellisense window pops up and tells us about the method and its parameter.

To support Intellisense, you need to add XML documentation to your method.  To start with, enter “///” on a blank line immediately preceding the first line of your method.  Visual Studio will create an empty template for you to fill in.

        /// <summary>
        ///
        /// </summary>
        /// <param name="numTimes"></param>
        public void Bark(int numTimes)

To finish the documentation, just enter a short description of the method within the <summary> tag and a description of each parameter within the <param> tags.

#299 – Intellisense Shows You Available Constructors

If you have several different constructors define for a class or a struct, Intellisense in Visual Studio will show you the different constructors that you can use.

Assume that you have a Dog class, with two different constructors, as follows:

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

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

        public Dog(string name)
            : this(name, 1)
        {
        }
    }

Because we have these two constructors, we can pass in either one or two parameters when using the new operator to construct a new instance of a Dog.

            Dog d1 = new Dog("Lassie");
            Dog d2 = new Dog("Django", 6);

Visual Studio will tell us, through Intellisense, that there are two constructors available.  Once the constructor signature pops up, you can use the arrow keys to cycle through the two options.

#298 – A struct Can Have Several Constructors

You can define more than one constructor for a struct, as long as the method signature for each constructor is different.

    public struct Point3D
    {
        public double x;
        public double y;
        public double z;

        public Point3D(double xi, double yi, double zi)
        {
            x = xi;
            y = yi;
            z = zi;
        }

        public Point3D(int n)
        {
            x = n;
            y = n;
            z = n;
        }
    }

Now you can instantiate a variable of this type in several different ways.

            Point3D pt1 = new Point3D();    // Default parameterless constructor
            Point3D pt2 = new Point3D(10.0, 20.0, 30.0);
            Point3D pt3 = new Point3D(5);

#297 – Three Different Ways to Initialize the Contents of a struct

You must assign a value to each field in a struct before using it, but there are several different ways to do this.

The first way is to assign the values directly, after you declare a new struct variable.

            Point3D myPoint;
            myPoint.x = 34.0;
            myPoint.y = 25.0;
            myPoint.z = 36.0;

The second way to assign values to all of the fields is to invoke the parameterless constructor, by using the new operator.  Note that you always get the built-in parameterless constructor–you cannot declare your own parameterless constructor in a custom struct.

This built-in constructor will initialize all fields to their default values.

            Point3D myPoint = new Point3D();

The last way to assign values is to invoke a custom constructor, assuming that your constructor assigns values to the fields.

            Point3D myPoint = new Point3D(10.0, 20.0, 30.0);

#296 – You Must Assign a Value to All Fields Before Using a struct

Before you can reference a struct in your code, all of its fields must first be initialized.  If all fields have not been initialized, the compiler will issue an error.

In the example below, we assign only two of the three public fields of a Point3D struct.  The compiler complains with the error:

Use of unassigned local variable ‘pt’

        static void Main()
        {
            Point3D pt;
            pt.x = 5.0;
            pt.y = 5.0;
            DoSomethingWithPoint(pt);
        }

        static void DoSomethingWithPoint(Point3D pt)
        {
            Console.WriteLine("{0},{1},{2}", pt.x, pt.y, pt.z);
        }

#295 – When Is a Static Constructor Called?

You cannot dictate when a static constructor will be called and you can’t call it directly.

More specifically, a static constructor will be called just before you do one of the following:

  • Create an instance of the type
  • Access any static data in the type
  • Start executing Main method (in the same class as the static constructor)

If we have the following implementation in the Dog class:

        public Dog(string name)
        {
            Console.WriteLine("Dog constructor");
            Name = name;
        }

        public static string Motto = "Wag all the time";

        static Dog()
        {
            Console.WriteLine("Static Dog constructor");
        }

And we create a Dog instance:

 Console.WriteLine("Here 1");
 Dog d1 = new Dog("Kirby");
 Console.WriteLine("Here 2");

We get this output (static constructor called before object instantiation):

Or if we access static data:

            Console.WriteLine("Here 1");
            string s = Dog.Motto;
            Console.WriteLine("Here 2");

The output is (static constructor called before accessing static data):