System ProgrammingLearn About IDisposable Interface in C# Programming

Learn About IDisposable Interface in C# Programming

C#-(18)---IDisposable-Interface-740X296

In the previous article, we discussed the concept of interfaces. An interface is like a contract that the class declares it’s compliance to it by implementing this interface. It is a promise that all methods contained in this interface will be exposed by the class. Let’s have a look at one of the most famous built-in language interfaces: the IDisposable interface.

The IDisposable interface

An object that implements this interface must expose the Dispose() method. The Dispose() typically contains logic that will be executed right before the object is trashed using the garbage collector. The garbage collector is responsible for freeing memory of any object that is no longer used, that is, no longer referenced in code. The Dispose() method is an excellent place to put code that will ensure that critical resources have been properly released before the object completely vanishes. C# offers one neat way to ensure that the Dispose() method is properly called: the using keyword.

A prominent example of using the using structure is database connections. If you haven’t worked with databases before, you should know, that to work with one, you have to establish a connection. C# provides several objects from connecting to databases. Such objects should be disposed after work is done with the database, in order to enhance application performance. In our example, we are using the SqlConnection, and the SqlCommand, both of which – by default – implement the IDisposable interface.  We’ll be applying the using structure to make sure object is disposed as soon as it is no longer needed.

using System.Data.SqlClient;

    class Program
    {
        static void Main(string[] args)
        {
            using (SqlConnection con = new SqlConnection("Server=localhost;Database=myDataBase;User Id=myUsername;Password=myPassword;"))
            using (SqlCommand cmd = new SqlCommand("SELECT * FROM users"))
            {
                con.Open();
                cmd.ExecuteNonQuery();
            }
        }
    }

NOTE: do not confuse the using structure with the using keyword that is used to reference other namespaces.

In this example, we create a new SqlConnection object and pass on the connection string to it. The connection string is just the information that the object uses to connect to the database, like the IP address or hostname, the username and password…etc. Notice how we enclosed the instantiation logic inside the using structure. This ensures that the con object will call the Dispose() method automatically as soon as it is no longer needed in code. Then we instantiated the SqlCommand object, which is responsible for carrying SQL commands to the database; it was enclosed in the using structure too.  To illustrate the concept even more, the above code has the same effect as the following:

        static void Main(string[] args)
        {
            SqlConnection con = new SqlConnection("Server=localhost;Database=myDataBase;User Id=myUsername;Password=myPassword;");
            try
            {
                con.Open();
                SqlCommand cmd = new SqlCommand();
                try 
                {
                    cmd.CommandText = "SELECT * FROM users";
                    cmd.ExecuteNonQuery();
                }
                finally
                {
                    if (cmd != null)
                        cmd.Dispose();
                }
            }
            finally
            {
                if (con != null)
                    con.Dispose();
            }
        }

This time we used the try…finally method (of course in a real world application you should also use a catch block but it was omitted here for brevity). The finally block ensures that the Dispose() method is called after we are done with our objects.

Class inheritance

This is another pillar of OOP. It is often regarded as one of the main reasons why object oriented programming was introduced, as it greatly facilitates code reuse.

Inheritance works the same way it works in real life. Consider this example: we have a parent class vehicle. A vehicle is very generic but it must have some fields like the number of seats, the color, and the maximum speed. It will also have some methods that define its behavior, like move(), stop(), and steer().  A child class like car will inherit all the fields and methods of the parent class vehicle as well as adds its own fields and methods that make it different in its own. Perhaps a car will introduce a style field (is it an SUV or a sports car), and tail-light() method that, well, lights up the tail light. Another child class such as boat will definitely has its own set of fields and methods that distinguish it from a car.

In programming, inheritance saves you from having to rewrite the same code to achieve the same logic. Let’s put the vehicle class example to code:

In Visual Studio, add a new class and call it Vehicle. It should look like the following:

class Vehicle
    {
        public int seats;
        public string color;
        public int maxSpeed;

        public void move()
        {

        }

        public void stop()
        {

        }

        public void steer()
        {

        }
    }

Now, add another class Car that inherits from Vehicle. It should look like the following:

class Car : Vehicle
    {
        public enum styles
        {
            sports,
            suv,
            fourbyfour
        }
        
        public styles style;
        
        public void tailLight()
        {
            Console.WriteLine("Tail light is on");
        }
    }

Because Car inherits from Vehicle, all the fields and methods defined in Vehicle are available to Car. In addition, we add fields and methods specific to Car. Now, we can create a Car method and have access to members of Car and Vehicle classes as follows:

static void Main(string[] args)
        {
            Car myCar = new Car();
            myCar.color = "red";
            myCar.maxSpeed = 200;
            myCar.style = Car.styles.sports;
            myCar.tailLight();
            Console.Read();
        }

But isn’t this the job of interfaces?

I hear you asking that question. I raised the same question when I first heard about interfaces and class inheritance. Actually, interfaces may be similar to class inheritance in that you expose the same methods that are used in the interface. But there are some important differences between the two concepts:

  1. If you implement an interface, you must implement all the methods defined in this interface.
  2. Interfaces do not provide initial code to methods. This means, it is the responsibility of the implementing class to write codes for the implemented methods. On the other hand, a base class can write default code for a method, and the child class may or may not override this code with its own.
  3. In C# you are not allowed to inherit from multiple classes, however, you can implement several interfaces at the same time

Learn Cloud Computing from Scratch for Beginners

Inheritance access levels

A field or method defined in a class is made available to the outside code according to the way it was declared. It is controlled by the accessibility modifier as follows:
Public: available to child classes as well as other code in the application
Protected: available only to child classes
Private: available to the container class only

It is advisable to declare your class variables as private and use getter and setter methods (properties). This will give you more control on the value assigned to your class field. You can also use it to make your fields “read-only” by omitting the set method. Consider the following example:

class Car : Vehicle
    {
        public enum styles
        {
            sports,
            suv,
            fourbyfour
        }
        
        private styles _style;

        public styles style 
        {
            get
            {
                return _style;
            }
            set
            {
                _style = value;
            }
        }
        
        public void tailLight()
        {
            Console.WriteLine("Tail light is on");
        }
    }

Here we changed the style field to be private. Private fields start with underscore (_), which is just a convention. C# provides special get and set methods that are used to read and modify the value of class fields. Notice that the set method uses the special value variable. The value variable will hold the value supplied to the set method. For example:

myCar.style = Car.styles.sports;

Internally, the value variable holds Car.styles.sports, and it will get assigned to the _style field.
The _style is not available to code outside the class. If anyone wants to get the _style value of myCar object, he must use the getter property like this:

myCar.style

If we omit the set method, this property can only be read (read-only).

Method overriding

As mentioned in the previous examples, public and protected methods defined in one class are available to any child classes. But what if you want to provide your own implementation for one of those methods? For example, the Vehicle class has a move() method, but the Car class wants to provide an alternative implementation for this method. In this case, the Vehicle class must declare this method as virtual to enable child classes to override it. Consider the following example:

    class Vehicle
    {
        public virtual void move()
        {
            Console.WriteLine("Vehicle is moving");
        }
    }

    class Car : Vehicle
    {
        public override void move()
        {
            Console.WriteLine("Car is moving");
        }

    }
        static void Main(string[] args)
        {
            Vehicle myCar = new Car();
            myCar.move();
            Console.Read();
        }

The output of running the above code will be “Car is moving”.
Conclusion
In this post, we started by exploring the useful built-in interface IDisposbale. Any object that implements this interface (like database connection objects) can call a Dispose() method, where any pre-object-destruction code should be placed. You also learned about the using shorthand, which provides an easy way to automatically call the Dispose() method on objects that implement it once it is no longer used.

Then, we had a look at the inheritance mechanism in C#, and how it is used to allow objects to share code and functionality. You also learned how to control this inheritance by using accessibility modifiers, and how to use getter and setter methods to govern the way fields get read and modified by external code. Finally, you learned about method overriding, which is one way of making the child class implement a different behavior to the same method of the parent class.

In the next post, we are going to learn about abstract classes, then we start discussing polymorphism. See you then.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Exclusive content

- Advertisement -

Latest article

21,501FansLike
4,106FollowersFollow
106,000SubscribersSubscribe

More article

- Advertisement -