In this article we’ll learn all about C# with some of the best articles on C# Corner which I find most helpful for every C# Developer.
Here is the list of the 10 most important things in C#.
- Advantages of C#
- Future of C#
- Abstraction in C#
- Encapsulation in C#
- Inheritance in C#
- Polymorphism in C#
- Delegates in C#
- Collections in C#
- Exception handling in C#
- File Handling in C#
1. Advantages of C# over Java
I have found some interesting advantages of C# over Java and for that I have also won the prize from the Java team...!!. So I want to share it with all people so others can also know about it.
- C# being a .NET language, it supports language interoperability, i.e. C# can access code written in any .NET compliant language and can also inherit the classes written in these languages. This is not possible in Java.
- The code written in C#, on compilation generates an ‘.exe' or ‘.dll' file which is also called Portable Executable file. These files contain MSIL (Microsoft Intermediate Language) code. As against this, the Java code on compilation generates a ‘.class' file, which contains bytecode.
- The portable executable file of C# can contain any number of classes, whereas, the ‘.class' file in Java contains only one class.
- The methods in C# are not virtual by default. On the contrary, methods in Java are virtual by default, which degrades the performance.
- The classes in C# are grouped in Namespaces, whereas, classes in Java are grouped in Packages.
- The C# namespaces are not related to the directories. The packages in Java are directly related with the directory names.
- The variables of primitive data types in C# are more powerful. This is because even though they are not objects functions can be called using them. The variables of primitive data types in Java cannot call functions.
- C# has features like Properties and Indexers. These features are not available in the Java language.
- C# supports Structures, Operator Overloading and Pre-processors directives, whereas, Java has none of them.
- Through C# we can easily call Windows API function and access COM components which is quite difficult in Java.
For more follow the link:
2. Future of C#
Today, C# is not only a Windows development programming language but can be used to build Web applications, Windows store apps, and mobile apps including iOS and Android. C# can also do more than that. If you’ve not already read my article, I highly recommend going and reading What C# Can Do For You.
At the Build 2016 event, Microsoft made several exciting announcements and one of them was integrating Xamarin as a part of Visual Studio “15” and beyond. Now C# developers can build iOS and Android apps that can spit out native iOS and Android code.
...the future of C# is very bright.
In the following Channel 9 video, Microsoft’s Dustin Campbell and Mads Torgersen talk about the future of C#.
Here are some of the bullet points from the video:
3. Abstraction in C#
The word abstract means a concept or an idea not associated with any specific instance. In programming we apply the same meaning of abstraction by making classes not associated with any specific instance. The abstraction is done when we need to only inherit from a certain class, but do not need to instantiate objects of that class. In such case the base class can be regarded as "Incomplete". Such classes are known as an "Abstract Base Class".
Abstract Base Class
There are some important points about Abstract Base Class :
- An Abstract Base class can not be instantiated; it means the object of that class can not be created.
- Class having abstract keyword and having abstract keyword with some of its methods (not all) is known as an Abstract Base Class.
- Class having Abstract keyword and having abstract keyword with all of its methods is known as pure Abstract Base Class.
- The method of abstract class that has no implementation is known as "operation". It can be defined as abstract void method ();
- An abstract class holds the methods but the actual implementation of those methods is made in derived class.
Lets have a look at this code!
- abstract class animal
- {
- public abstract void eat();
- public void sound()
- {
- Console.WriteLine("dog can sound");
- }
- }
This is the Abstract Base Class, if I make both of its methods abstract then this class would become a pure Abstract Base Class.
Now we derive a class of 'dog' from the class animal.
- abstract class animal
- {
- public abstract void eat();
- public void sound()
- {
- Console.WriteLine("dog can sound");
- }
- }
- class dog: animal
- {
- public override void eat()
- {
- Console.WriteLine("dog can eat");
- }
- }
Here you can see we have 2 methods in the Abstract Base Class, the method eat() has no implementation; that is why it is being declared as 'abstract' while the method sound() has its own body so it is not declared as 'abstract'.
In the derived class we have the same named method but this method has its body.
We are doing abstraction here so that we can access the method of derived class without any trouble.
Let's have a look!
- class program
- {
- abstract class animal
- {
- public abstract void eat();
- public void sound()
- {
- Console.WriteLine("dog can sound");
- }
- }
- class dog: animal
- {
- public override void eat()
- {
- Console.WriteLine("dog can eat");
- }
- }
- static void Main(string[] args)
- {
- dog mydog = new dog();
- animal thePet = mydog;
- thePet.eat();
- mydog.sound();
- }
- }
Finally we created an Object 'mydog' of class dog, but we didn't instantiate any object of Abstract Base Class 'animal'.
According to "Ivor Horton" (a programmer of Java) an object can not be instantiated, but we can declare a variable of the Abstract Class type. If this statement is true then it could be possible:
animal thePet;
This is an object which is declared as thePet and its data type is the abstract base class 'animal'.
We can use this Object to store Objects of the subclass.
In the above code we declare an Object 'thePet', of the type animal (the Abstract Base Class) and simply copy the object of another object (only the reference is copied as they belong to reference type). Now we can use object 'thePet' just as object 'mydog'.
The output of this code would be,
dog can eat
dog can sound
For more follow the link:
4. Encapsulation in C#
The object oriented programming will give the impression very unnatural to a programmer with a lot of procedural programming experience. In Object Oriented programming Encapsulation is the first place. Encapsulation is the procedure of covering up of data and functions into a single unit (called class). An encapsulated object is often called an abstract data type. In this article let us see about it in a detailed manner.
NEED FOR ENCAPSULATION
The need of encapsulation is to protect or prevent the code (data) from accidental corruption due to the silly little errors that we are all prone to make. In Object oriented programming data is treated as a critical element in the program development and data is packed closely to the functions that operate on it and protects it from accidental modification from outside functions.
Encapsulation provides a way to protect data from accidental corruption. Rather than defining the data in the form of public, we can declare those fields as private. The Private data are manipulated indirectly by two ways. Let us see some example programs in C# to demonstrate Encapsulation by those two methods. The first method is using a pair of conventional accessor and mutator methods. Another one method is using a named property. Whatever be the method our aim is to use the data without any damage or change.
ENCAPSULATION USING ACCESSORS AND MUTATORS
Let us see an example of Department class. To manipulate the data in that class (String departname) we define an accessor (get method) and mutator (set method).
- using system;
- public class Department
- {
- private string departname;
- .......
-
- public string GetDepartname()
- {
- return departname;
- }
-
- public void SetDepartname(string a)
- {
- departname = a;
- }
- }
Like the above way we can protect the private data from the outside world. Here we use two separate methods to assign and get the required data.
- public static int Main(string[] args)
- {
- Department d = new Department();
- d.SetDepartname("ELECTRONICS");
- Console.WriteLine("The Department is :" + d.GetDepartname());
- return 0;
- }
In the above example we can't access the private data departname from an object instance. We manipulate the data only using those two methods.
For more follow the link:
5. Inheritance in C#
Inheritance is one of the three foundational principles of Object-Oriented Programming (OOP) because it allows the creation of hierarchical classifications. Using inheritance you can create a general class that defines traits common to a set of related items. This class can then be inherited by other, more specific classes, each adding those things that are unique to it.
In the language of C#, a class that is inherited is called a base class. The class that does the inheriting is called the derived class. Therefore a derived class is a specialized version of a base class. It inherits all of the variables, methods, properties, and indexers defined by the base class and adds its own unique elements.
Example
Diagram
The following diagram shows the inheritance of a shape class. Here the base class is Shape and the other classes are its child classes. In the following program we will explain the inheritance of the Triangle class from the Shape class.
-
- class Shape
- {
- public double Width;
- public double Height;
- public void ShowDim()
- {
- Console.WriteLine("Width and height are " +
- Width + " and " + Height);
- }
- }
-
-
- class Triangle: Shape
- {
- public string Style;
-
- public double Area()
- {
- return Width * Height / 2;
- }
-
- public void ShowStyle() {
- Console.WriteLine("Triangle is " + Style);
- }
- }
-
- class Driver
- {
- static void Main()
- {
- Triangle t1 new Triangle();
- Triangle t2 new Triangle();
- t1.Width = 4.0;
- t1.Height = 4.0;
- t1.Style = "isosceles";
- t2.Width = 8.0;
- t2.Height = 12.0;
- t2.Style = "right";
- Console.WriteLine("Info for t1: ");
- t1.ShowStyle();
- t1.ShowDim();
- Console.WriteLine("Area is " + t1.Area());
- Console.WriteLine();
- Console.WriteLine("Info for t2: ");
- t2.ShowStyle();
- t2.ShowDim();
- Console.WriteLine("Area is " + t2.Area());
- }
- }
The output from this program is shown here:
Info for t1
Triangle is isosceles
Width and height are 4 and 4
Area is 8
Info for t2:
Triangle is right
Width and height are 8 and 12
Area is 48
For more follow the link:
6. Polymorphism in C#
Polymorphism means the same operation may behave differently on different classes.
- Example of Compile Time Polymorphism: Method Overloading
- Example of Run Time Polymorphism: Method Overriding
- Example of Compile Time Polymorphism
- Method Overloading: Method with same name but with different arguments is called method overloading.
- Method Overloading forms compile-time polymorphism.
Example of Method Overloading
- class A1
- {
- void hello()
- {
- Console.WriteLine("Hello");
- }
- void hello(string s)
- {
- Console.WriteLine("Hello {0}", s);
- }
- }
Example of Run Time Polymorphism
- Method Overriding: Method overriding occurs when child class declares a method that has the same type arguments as a method declared by one of its superclass.
- Method overriding forms Run-time polymorphism.
Note
By default functions are not virtual in C# and so you need to write “virtual” explicitly. While by default in Java each function are virtual.
Example of Method Overriding
- Class parent
- {
- virtual void hello()
- {
- Console.WriteLine("A D Patel");
- }
- }
- Class child: parent
- {
- override void hello()
- {
- Console.WriteLine("R A Patel");
- }
- }
- static void main()
- {
- parent objParent = new child();
- objParent.hello();
- }
-
R A Patel
For more follow the link:
7. Delegates in C#
Delegate is one of the base types in .NET. Delegate is a class, which is used to create delegate at runtime.
Delegate in C# is similar to a function pointer in C or C++. It's a new type of object in C#. Delegate is very special type of object as earlier the entire the object we used to defined contained data but delegate just contains the details of a method.
Need of delegate
There might be a situation in which you want to pass methods around to other methods. For this purpose we create delegate.
A delegate is a class that encapsulates a method signature. Although it can be used in any context, it often serves as the basis for the event-handling model in C# but can be used in a context removed from event handling (e.g. passing a method to a method through a delegate parameter).
One good way of understanding delegates is by thinking of a delegate as something that gives a name to a method signature.
Example
- public delegate int DelegateMethod(int x, int y);
Any method that matches the delegate's signature, which consists of the return type and parameters, can be assigned to the delegate. This makes is possible to programmatically change method calls, and also plug new code into existing classes. As long as you know the delegate's signature, you can assign your own-delegated method.
This ability to refer to a method as a parameter makes delegates ideal for defining callback methods.
Delegate magic
In class we create its object, which is instance, but in delegate when we create instance that is also referred to as delegate (means whatever you do you will get delegate).
Delegate does not know or care about the class of the object that it references. Any object will do; all that matters is that the method's argument types and return type match the delegate's. This makes delegates perfectly suited for "anonymous" invocation.
Benefit of delegates
In simple words delegates are object oriented and type-safe and very secure as they ensure that the signature of the method being called is correct. Delegate helps in code optimization.
Types of delegates
- Singlecast delegates
- Multiplecast delegates
Delegate is a class. Any delegate is inherited from base delegate class of .NET class library when it is declared. This can be from either of the two classes from System.Delegate or System.MulticastDelegate.
Singlecast delegate
Singlecast delegate point to single method at a time. In this the delegate is assigned to a single method at a time. They are derived from System.Delegate class.
Multicast Delegate
When a delegate is wrapped with more than one method that is known as a multicast delegate.
In C#, delegates are multicast, which means that they can point to more than one function at a time. They are derived from System.MulticastDelegate class.
For more follow the link:
8. Collections in C#
“.NET” offers a variety of collections, such as ArrayList, Hashtable, queues, Dictionaries. Collections are abstractions of data algorithms. An ArrayList is an abstract dynamic array, a Hashtable collection abstracts a lookup table, a Queues collection abstracts queues and so on. In addition to that, collections implement the ICollection, IEnumerable and IClonable interfaces. The detailed specification for each collection is found under the System.Collection namespace.
ArrayList Collection
An ArrayList is a dynamic array and implements the IList interface. Each element is accessible using the indexing operator. While the traditional array has a fixed number of elements, in the case of Array List, elements can be added or removed at run time.
We can create an object of ArrayList using a general type of syntax as follows;
ArrayList obj = new ArrayList();
Here you can use the new keyword to create an instance of the ArrayList object. You don't need to specify the size. Once you have an empty ArrayList object, you can use the Add() method to add elements to it,as in,
- obj.Add("item1");
- obj.Add("2");
- obj.Add("Delhi");
Each new item in the ArrayList is added to the end of the list, so it has the largest index number. If you wanted to add an item in the middle of the list, then you can use "Insert()" with a numeric argument as follows,
You can also remove members of the ArrayList using either Remove() or RemoveAt() methods as in the following,
- Obj.Remove("item1");
- Obj.RemoveAt(3);
Benefits of ArrayLists
- Insert Elements: An ArrayList starts with a collection containing no elements. You can add them in any position as you choose them.
- Automatic Resizing: you do not need to specify the array size; as you add elements, the array automatically ensures there is enough memory for the array.
- Flexibility When Removing Elements: you can remove any element from an Arraylist very easily.
Limitations of ArrayLists
The flexibility of ArrayList comes at a cost of performance. Since memory allocation is a very expensive business, the fixed number of elements of the simple array makes it much faster to work with.
Note - ArrayLists are slower and more resource-intensive than a conventional array.
Simple ArrayList Example
The following example shows an array list with an #ff0000 size. Elements are added dynamically as required. We are adding elements using the "Add()" method as well as using the "Insert()" method at a specific location. Later we are displaying all the elements by iterating through the list.
- using System;
- using System.Collections;
- namespace CollectionApp
- {
- class Program
- {
- static void Main(string[] args)
- {
-
- ArrayList obj = new ArrayList();
-
- obj.Add("India");
- obj.Add("USA");
- obj.Add("Russia");
- obj.Add("300");
-
- obj.Insert(2, "Japan");
-
- for (int i = 0; i < obj.Count; i++)
- {
- Console.WriteLine("At Index[" + i + "]= " + obj[i].ToString());
- }
- Console.WriteLine("____________");
- Console.WriteLine("Press any key");
- Console.ReadKey();
- }
- }
- }
After building and running this program, the output of the program is as in the following,
For more Collections follow the link:
9. Exception handling in C#
Exception handling is a built-in mechanism in .NET framework to detect and handle run time errors. The .NET framework contains many standard exceptions. The exceptions are anomalies that occur during the execution of a program. They can be because of user, logic or system errors. If a user (programmer) does not provide a mechanism to handle these anomalies, the .NET run time environment provides a default mechanism that terminates the program execution.
C# provides the three keywords try, catch and finally to do exception handling. The try block encloses the statements that might throw an exception whereas catch handles an exception if one exists. The finally can be used for doing any clean-up process.
The general form of try-catch-finally in C# is shown below.
- try
- {
-
- } catch (Type x)
- {
-
- } finally
- {
-
- }
If any exception occurs inside the try block then the control transfers to the appropriate catch block and later to the finally block.
But in C#, both catch and finally blocks are optional. The try block can exist either with one or more catch blocks or a finally block or with both catch and finally blocks.
If there is no exception occurring inside the try block then the control directly transfers to the finally block. We can say that the statements inside the finally block is executed always. Note that it is an error to transfer control out of a finally block by using break, continue, return or goto.
In C#, exceptions are nothing but objects of the type Exception. The Exception is the ultimate base class for any exceptions in C#. The C# itself provides a couple of standard exceptions. Or even the user can create their own exception classes, provided that this should inherit from either the Exception class or one of the standard derived classes of the Exception class like DivideByZeroExcpetion or ArgumentException and so on.
For more follow the link:
10. File Handling in C#
The System.IO namespace provides four classes that allow you to manipulate individual files, as well as interact with a machine directory structure. The Directory and File directly extends System.Object and supports the creation, copying, moving and deletion of files using various static methods. They only contain static methods and are never instantiated. The FileInfo and DirecotryInfo types are derived from the abstract class FileSystemInfo type and they are typically, employed for obtaining the full details of a file or directory because their members tend to return strongly typed objects. They implement roughly the same public methods as a Directory and a File but they are stateful and the members of these classes are not static.
In the .NET framework, the System.IO namespace is the region of the base class libraries devoted to file based input and output services. Like any namespace, the System.IO namespace defines a set of classes, interfaces, enumerations, structures and delegates. The following table outlines the core members of this namespace.
Class Types | Description |
Directory/ DirectoryInfo | These classes support the manipulation of the system directory structure. |
DriveInfo | This class provides detailed information regarding the drives that a given machine has. |
FileStream | This gets you random file access with data represented as a stream of bytes. |
File/FileInfo | These sets of classes manipulate a computer's files. |
Path | It performs operations on System.String types that contain file or directory path information in a platform-neutral manner. |
BinaryReader/ BinaryWriter | These classes allow you to store and retrieve primitive data types as binary values. |
StreamReader/StreamWriter | Used to store textual information to a file. |
StringReader/StringWriter | These classes also work with textual information. However, the underlying storage is a string buffer rather than a physical file. |
BufferedStream | This class provides temp storage for a stream of bytes that you can commit to storage at a later time. |
The System.IO provides a class DriveInfo to manipulate the system drive related tasks. The DriveInfo class provides numerous details such as the total number of drives, calculation of total hard disk space, available space, drive name, ready status, types and so on. Consider the following program that shows the total disk drives.
- DriveInfo[] di = DriveInfo.GetDrives();
- Console.WriteLine("Total Partitions");
-
- foreach(DriveInfo items in di)
- {
- Console.WriteLine(items.Name);
- }
The following code snippets perform the rest of the DriveInfo class method operations in details. It displays specific drive full information.
- using System;
- using System.IO;
-
- namespace DiskPartition
- {
- class Program
- {
- static void Main(string[] args)
- {
- DriveInfo[] di = DriveInfo.GetDrives();
-
- Console.WriteLine("Total Partitions");
- Console.WriteLine("---------------------");
- foreach(DriveInfo items in di)
- {
- Console.WriteLine(items.Name);
- }
- Console.Write("\nEnter the Partition::");
- string ch = Console.ReadLine();
-
- DriveInfo dInfo = new DriveInfo(ch);
-
- Console.WriteLine("\n");
-
- Console.WriteLine("Drive Name::{0}", dInfo.Name);
- Console.WriteLine("Total Space::{0}", dInfo.TotalSize);
- Console.WriteLine("Free Space::{0}", dInfo.TotalFreeSpace);
- Console.WriteLine("Drive Format::{0}", dInfo.DriveFormat);
- Console.WriteLine("Volume Label::{0}", dInfo.VolumeLabel);
- Console.WriteLine("Drive Type::{0}", dInfo.DriveType);
- Console.WriteLine("Root dir::{0}", dInfo.RootDirectory);
- Console.WriteLine("Ready::{0}", dInfo.IsReady);
-
- Console.ReadKey();
- }
- }
- }
After compiling this program, it displays nearly every detail of disk drives and a specific drive as in the following,
Reading and Writing to Files
Reading and writing operations are done using a File object. The following code snippet reads a text file located in the machine somewhere.
- private void button1_Click(object sender, EventArgs e)
- {
- try
- {
- textBox2.Text = File.ReadAllText(txtPath.Text);
- } catch (FileNotFoundException)
- {
- MessageBox.Show("File not Found....");
- }
- }
Here, first the user interface asks the user to enter the path of the file that he wanted to display. Later that path is passed to the File method ReadAllText() method that reads all the text integrated in the file and displays it over the text box.
Besides reading a file, we can write some contents over an existing text file by the File class WriteAllTest() method as in the following,
- File.WriteAllText(@"d:\test.txt", textBox2.Text);
It takes a path to save the file and content input method medium such as a text box or any other control. The following images depict a text file reading by entering its corresponding path,
Stream
The .NET provides many objects such as FileStream, StreamReader/Writer, BinaryReader/Writer to read from and write data to a file. A stream basically represents a chunk of data flowing between a source and a destination. Stream provides a common way to interact with a sequence of bytes regardless of what kind of devices store or display the bytes. The following table provides common stream member functions,
Methods | Description |
Read()/ ReadByte() | Read a sequence of bytes from the current stream. |
Write()/WriteByte() | Write a sequence of bytes to the current stream. |
Seek() | Sets the position in the current stream. |
Position() | Determine the current position in the current stream. |
Length() | Return the length of the stream in bytes. |
Flush() | Updates the underlying data source with the current state of the buffer and then clears the buffer. |
Close() | Closes the current stream and releases any associated stream resources. |
FileStream
A FileStream instance is used to read or write data to or from a file. In order to construct a FileStream, first we need a file that we want to access. Second, the mode that indicates how we want to open the file. Third, the access that indicates how we want to access a file. And finally, the share access that specifies whether you want exclusive access to the file.
Enumeration | Values |
FileMode | Create, Append, Open, CreateNew, Truncate, OpenOrCreate |
FileAccess | Read, Write, ReadWrite |
FileShare | Inheritable, Read, None, Write, ReadWrite |
The FileStream can read or write only a single byte or an array of bytes. You will be required to encode the System.String type into a corresponding byte array. The System.Text namespace defines a type named encoding that provides members that encode and decode strings to an array of bytes. Once encoded, the byte array is persisted to a file with the FileStream.Write() method. To read the bytes back into memory, you must reset the internal position of the stream and call the ReadByte() method. Finally, you display the raw byte array and the decoded string to the console.
- using(FileStream fs = new FileStream(@ "d:\ajay123.doc", FileMode.Create))
- {
- string msg = "first program";
- byte[] byteArray = Encoding.Default.GetBytes(msg);
- fs.Write(byteArray, 0, byteArray.Length);
- fs.Position = 0;
-
- byte[] rFile = new byte[byteArray.Length];
-
- for (int i = 0; i < byteArray.Length; i++)
- {
- rFile[i] = (byte) fs.ReadByte();
- Console.WriteLine(rFile[i]);
- }
-
- Console.WriteLine(Encoding.Default.GetString(rFile));
- }
BinaryReader and BinaryWriter
The BinaryReader and Writer class allows you to read and write discrete data types to an underlying stream in a compact binary format. The BinaryWriter class defines a highly overloaded Write method to place a data type in the underlying stream.
Members | Description | Class |
Write | Write the value to current stream | BinaryWriter |
Seek | Set the position in the current stream | BinaryWriter |
Close | Close the binary reader | BinaryWriter |
Flush | Flush the binary stream | BinaryWriter |
PeekChar | Return the next available character without advancing the position in the stream | BinaryReader |
Read | Read a specified set of bytes or characters and store them in the incoming array. | BinaryReader |
For more examples follow the link:
Further Recommendations
Want more on C#? Here is list of recommended resources.