Skip to content

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

Know the Default Visibilities for Classes, Nested Classes, and Members

This guide explains how classes are defined in C# and how the scope of different objects can be used for powerful code creation.

Dec 5, 2019 • 11 Minute Read

Introduction

C# is a powerful and simple general-purpose programming language. It is an object-oriented language, implying objects are created via classes and will have various ranges or visibilities in the development environment. Understanding the default visibilities of classes, nested classes and members is crucial for creating efficient code as per the specified requirements.

Classes in C#

A class is the building block of C#. It is used to form object(s), and functions are performed on them which form the base of the whole program or software. The class is what defines the meaning, i.e., the type and scope of the object, and serves as a blueprint. The instance of a class is object. Other concepts associated with a class are its methods (grouped statements that perform a particular function) and variables (a name given to storage area depending on its type).

How to Define a Class

Start by mentioning the keyword Class and then the name of the class. The class body is defined by curly braces, as in the example below:

      <access specifier> class  ClassName {
    // Defining the class, members and variables
}
    

Other than the basic declaration, there are some additional attributes that can be specified along with the class definition according to your need.

  • Modifiers: The default access specifier is Internal and if not mentioned, access for methods is Private.
  • Class Identifier: The variable of type class is mentioned here. The identifier is capitalized by convention.
  • Base class/ Superclass: If a class is inherited (elaborated further), the name of its base class can be mentioned, preceded by the colon :.
  • Interfaces: A number of interfaces can be implemented by a class which is specified using the colon :. It is allowed for a class to implement more than one interface.
  • Body: The class body is defined within the curly braces {}.

To familiarize yourself with these concepts, please see the simple example below.

      <public> class  StudentInfo {
   // member variables
   <public> <int> Rollno;
   <public> <string> Name;
   ...
   <private> <int> primarykey;
   // member methods
   <public> <int> firstfunction(int,int) {
      // define method here
   }
   <private> <string> second function(parameter_list) {
      // define method here
   }
  }
    

The following example will demonstrate all the aspects we have learned so far in the example code.

Live Demo

      using System;

namespace SimpleInterest {
   class Money {
      public double income;   // Income of First Person in family
      public double loan;  // Income of Second Person in family
      public double interest;   // The interest on a loan to be paid
   }
   class Expenses {
      static void Main(string[] args) {
         Money Money1 = new Money();   // Declare Money1 of type Money
         Money Money2 = new Money();   // Declare Money1 of type Money
         double expense = 0.0;    // Store the expenses here

         // Money 1 specification
         Money1.income = 5000.0;
         Money1.loan = 600.0;
         Money1.interest = 0.7;

         // Money 2 specification
         Money2.income = 10000.0;
         Money2.loan = 1200.0;
         Money2.interest = 0.85;
           
         // Expenses of first person 
         expense = Money1.income - Money1.loan * Money1.interest;
         Console.WriteLine("Expenses of First Person : {0}",  expense);

         // Expenses of second person
         expense = Money2.income - Money2.loan * Money2.interest;
         Console.WriteLine("Expenses of Second Person : {0}", expense);
         Console.ReadKey();
      }
   }
}
    

At compilation, we get the final result.

      Expenses of First Person : 4580
Expenses of Second Person : 8980
    

In the same manner, you can use the live demo feature to write and practice your own code too.

Please note:

  • The dot operator can be used for accessing the class variables, which acts as the link between the class and the member name.
  • Data type will specify what type of variable it is. Meanwhile, Return Type is for the data type of the data the method returns, if present.

Member Functions of a Class

Member functions are called so because they are defined within the class body. Consequently, they have the same prototype as other variables defined in a class. They will operate on the objects that belong to their own class and will have access to all the members of a class for that specific object.

Member Variables are essentially the attributes of a given object. They are private so that encapsulation can be implemented. In C#, encapsulation is the ability of an object to conceal its behavior and the associated data if it is not necessary for the user. Through this property, a set of methods can be considered and acted upon as a single unit. They can be accessed via the public member functions.

To understand the concept of member functions and their scope, let us look at the following example.

      using System;

namespace MoneyApplication {
   class Money {
      private double income;   
      private double loan;  
      private double interest;   
      
      public void setIncome( double inc ) {
         income = inc;
      }
      public void setLoan( double lon ) {
         loan = lon;
      }
      public void setInterest( double itr ) {
         interest = itr;
      }
      public double getExpense() {
         return income * loan * interest;
      }
   }
   class Moneytester {
      static void Main(string[] args) {
         Money Money1 = new Money();   // Declare Money1 of type Money
         Money Money2 = new Money();
         double expense;
         
         // Declare Money2 of type Money
         // Money 1 specification
         Money1.setIncome(60.0);
         Money1.setLoan (57.0);
         Money1.setInterest(0.56);
         
         // Money 2 specification
         Money2.setIncome(20.0);
         Money2.setLoan(24.0);
         Money2. setInterest (0.09);
         
         // volume of Money 1
         expense = Money1.getExpense();
         Console.WriteLine("Expense of First Person ( Money1)  : {0}" ,expense);
         
         // volume of Money 2
         expense = Money2.getExpense();
         Console.WriteLine("Expense of Second Person ( Money2) : {0}", expense);
         
         Console.ReadKey();
      }
   }
}
    

Constructors

A constructor is a special type of class member function which is executed to create a new object of that class. It implements the behavior of that class in the object.

  • It will always have the same name as the class.
  • It has no return type.
  • By default, a constructor has no parameters. But if desired, there are parameterized constructors which assign the initial value to the object at the time of object creation.

Destructors

A destructor is also a special type of member function of a particular class executed when the object of its class is going out of scope.

  • Has the same name as the class with a prefixed tilde (~).
  • Does not return a value.
  • Does not take any parameters.
  • Useful for releasing memory before a program terminates.
  • Cannot be overloaded or inherited.

Objects

An object is the most basic unit in OOPS and the languages that implement this practice. Once an object is created, it interacts by invoking functions. They can be thought of as the real-life entities in the programming world.

Instantiating a Class: A class is instantiated by creating an object. A given class can have any number of objects.

Initializing an object: The new operator allocates memory for a new object by initiating the class and returns a reference to that memory location.

The C# compiler can differentiate between constructors based on the number of arguments and their types.

Nested Classes

In C#, one class can be defined with the definition of another class. These are known as nested classes. They allow the user to clump classes that are used for one purpose logically or together. This enhances encapsulation properties and makes the code more readable and manageable.

For example:

      using System;
// Outer class
public class OuterClass {
	// Method of outer class
    public void methodA(){
        Console.WriteLine("Outer class method called");
    }
    // Inner class
    public class InnerClass {
    	// Method of inner class
        public void methodB() {
            Console.WriteLine("Inner class Method called");
        }
    }
}
// Driver Class
public class Program {
    // Main method
    static public void Main(){
        // Create the instance of outer class
        OuterClass obj1 = new OuterClass();
        obj1.methodA();
        
        /* 
        This statement gives an error because you are not allowed 
        to access inner class methods with outer class objects.
        obj1. methodB();
        */
        
        // Creating an instance of inner class                              
        OuterClass.InnerClass obj2 = new OuterClass.InnerClass();            
        // Accessing the method of inner class
        obj2.methodB(); 
    } 
}
    

The output of this code is:

      Outer class method called
Inner class Method called
    

Note:

  • A nested class can be declared with any access modifier, namely private, public, protected, internal, protected internal, or private protected.

  • An outer class cannot directly access inner class members, as visible in the example above.

  • It is possible to create objects of inner class in the outer class.

  • An inner class is allowed to access a static member declared in outer class. A method is shown below:

    // Main Driver Class 
    public class DriverClass { 
        // Main method 
        static public void Main() {  
            // To access the static methodA of the inner class 
            OuterClass1.InnerClass2.methodA(); 
        } 
    } 
    

Some things to keep in mind with regard to nested classes:

    • The inner class can access any non-static member that has been declared in the outer class.

    • Scope of a nested class is limited by the scope of its (outer) enclosing class.

    • If nothing is specified, the nested class is private (default).

    • Any class can be inherited into another class in C# (including a nested class).

    • The user can inherit a nested class from outer class.

Conclusion

This article explains how classes are defined in C# and how the scope of different objects can be used for powerful code creation. Armed with this knowledge, anyone can set preferences, permissions for using objects and polymorphism, etc. for fewer lines of code and better performance optimization.

Happy learning C#!