Say NO to Anti-viruses

July 7th, 2008

Anti-viruses today, are increasingly becoming more and more resource hungry. Gone are the days when you could keep one on your machine while doing your daily computations. Without a multi-core processor you are doomed to even attempt to multi-task with your applications when a scan is in progress. Not all of us can keep up with the constant hardware upgrades that each new version of these softwares require.

This is why I have said NO to memory resident anti-viruses. You can easily go on without them by following some basic precautions. Let us look at the most common ways that viruses infect a computer.

Downloaded Applications from the Internet

Such problems never occur if the source of the application is a trusted company such as Microsoft, Yahoo, Download.com, Softpedia, etc. If you don’t fully trust a brand or if its new to you, do some googling with the keyword virus along with the name of the company or the concerned product. It is very likely that if somebody has had problems with any such softwares, they would have reported it somewhere on the Internet and it is our responsibility to do the same and keep the net safe.

A greater issue with internet downloads is the widespread use of pirated softwares. Cracked/Patched editions of the softwares may allow users to use them unrestricted. But, they are also bloated with Trojans and viruses that steal away your sensitive information.

Removable Media

Applications in removable media such as Pen Drives & CD/DVD ROMs spread the viruses when they are shared among computers. The infection only occurs when an infected file is executed on the machine. Never execute doubtful applications received in untrustworthy or custom burned discs. Remember, viruses these days are silent and have no real visible interfaces. They run in the background logging your key-strokes and monitoring your activities. Thereafter, the information is sent to the hackers’ website.

Not executing applications alone will not solve the problem. Many viruses use the Autorun feature in Windows to automatically execute the application when the disc is inserted. Disabling Autorun in Windows XP is a solution to this problem. Vista’s User Access Control (UAC) lets you choose whether to execute an Autorun program residing in a disc.

Sharing USB Drives

Pen Drive viruses spread by replicating themselves onto drives as soon as they are plugged into the port on an infected PC. The infection consists of two files – the infected application (EXE file) and an Autorun.inf file which automatically executes the infected application on a system when the Pen Drive is jacked in.

Because the file system in Pen Drives resembles that of a Hard Disk Drive, the write operations are trivial for the lightweight viruses. This vulnerability does not exist on CD/DVD ROMs because burning to discs is a much more complex job.

Worms in Network

Worms are one of the most dangerous kinds of viruses. They exploit the security vulnerabilities in Operating Systems to spread without notice across the network(s). Whenever a new worm with the ability to exploit such vulnerabilities is released, thousands of computers get infected and turned into zombie machines. Its imperative to install a good Firewall if your computer is connected to the Internet.

Popups in Sites

Ironically, many viruses are spread via popups in Web Pages that claim to have found virus infections on your systems. New users unaware of this, install their so called “Solutions” and let them into their system. NEVER, and I mean NEVER install such applications. No web page can scan and detect Viruses & Spywares on your system, unless off course supported by a browser Add-On which installs a scanner on the system and that too with your permission.

These are only a few but common methods viruses spread by. The average user can easily protect himself from these by exercising his experience. Without a heavy Antivirus the performance & responsiveness of the system is very satisfying, more so if you are a heavy multi-tasker. All having said & done, it is wise to install an Antivirus once in a while and do a full system scan, after which the program can be de-installed.

Tips

Adding two numbers without using the + Operator

March 27th, 2008

This is pretty easy to accomplish as Minus Minus maketh plus.

int A = 10;
int B = 5;
Console.WriteLine(A - -B);
Console.Read();

Google

uCertify – The fastest way to IT certification

January 7th, 2008

uCertify PrepEngineuCertify provides an interactive software that helps you in preparing for the various vendor certification exams. They provide PrepKits for Microsoft, CompTIA, CIW, Oracle, Sun Java, Cisco, Adobe and EC-Council. Whatever be the certification you are appearing for, you are sure to find a PrepKit for it. They even back all the PrepKits with a 100% money back guarantee, if you cannot clear the exam in your first attempt.

The PrepKits comprise of a variety of tests. The Diagnostic test lets you assess your current level of preparation while the Practice tests resemble the actual vendor certification examination, both in terms of format and difficulty. The Final test, designed to be even harder than vendor exam and a customizable test complete the list.

The PrepEngine is the central point for all the PreKits you have purchased. The interface is intuitively designed and requires no real time to get accustomed with. Other PrepKits can be installed and switched onto from within the application. Keyboard shortcuts facilitate working with the software without having to switch your hands back and forth between the keyboard and mouse. They also frequently update the PrepEngine (having myself experienced one such event during the course of writing this review). The application help is a bit cramped up because they don’t feature any categorization, indexing or search facility.

A variety of reports showing your performance with respect to the exam objectives and tests already taken are at your disposal. The PrepKits also contain study notes, tips, advanced articles and a well compiled listing of How Tos with media in the form of images.

Summing it up, the uCertify PrepKits are an excellent worth of your precious time and money. In the unlikely event of not getting through the certification exam, you can always get your money back.

Good News

Readers of Maxotek Blog can now avail a 10% discount on the uCertify PrepKit of their choice by using the discount code given below.

Discount Code

Shareware

How to copy Array values by value and not by reference.

October 28th, 2007

When you try to copy the value of one Array into another, you actually end up having two references to the same array. This is because an Array is a reference type.

int[] A = { 1, 2, 3 };
int[] B = A;
B[1] = 69;
Console.WriteLine(A[1]);

The above code would give an output of 69. As you can see, changes made to the elements of array B are applied to those of array A.

To do a copy by value you need to iterate through each of the Array elements in the source array and assign the value to the corresponding index in the destination array.

1
2
3
4
5
6
7
8
int[] A = { 1, 2, 3 };
 
// Set the Size of Array B to be the same as that of Array A.
int[] B = new int[A.Length];
for (int I = 0; I < A.Length; I++)
{
    B[I] = A[I];
}

There is a much simpler way to do this using the static method Copy of the Abstract class Array.

int[] A = { 1, 2, 3 };
 
// Set the Size of Array B to be the same as that of Array A.
int[] B = new int[Arr.Length];
Array.Copy(A, 0, B, 0, Arr.Length);

The Copy method is overloaded into 4 forms with two variations:-

Array.Copy(int[] SourceArray, int[] DestinationArray, int NumberOfElementsToCopy);
Array.Copy(int[] SourceArray, int SourceIndexToStartCopyFrom,
int[] DestinationArray, int DestinationIndextToStartCopyFrom, int NumberOfElementsToCopy);

The remaining two forms are the long counterparts of these two.

Google

What is Convert.ToInt32(Console.ReadLine()) Method In C#

October 28th, 2007

The method Console.ReadLine always reads the input from the user in the form of a string. To get an integer value from the user, this string needs to be converted to Integer. The Convert.ToInt32 does this.

Example Code:-

Console.WriteLine("Please enter a number");
int Num = Convert.ToInt32(Console.ReadLine());

Google

Can Destructors Be Parameterized?

October 28th, 2007

Destructors being automatically invoked, cannot be Parameterized.

Google

C# Tutorial : Lesson 15 – Error Handling

October 26th, 2007

There are three types of errors that can occur in your application. These are:-

  • Syntax Errors
  • Runtime Errors or Exceptions
  • Logical Errors

Syntax errors occur due to ill-formed codes. The cause can be a misspelled keyword, improperly constructed statements, absence of punctuations, such as line terminators, etc. The resulting code cannot be until all of these errors are removed.

Example:-

In this case the keyword Class is misspelled as Clas. Notice how the Visual Studio IDE highlights the error even before compilation starts. This is possible because of background compiling which is utilized in almost all modern Programming IDEs.

Runtime errors or Exceptions are erroneous situations in the runtime. The simplest example can be a division by Zero which results in a “Division by Zero” exception to be raised. These are different from Syntax errors in the sense that the compiler cannot detect these and hence the application compiles.

Click on the image to see the full screen version.

In the above program, the application halts due to a DivideByZeroException. Since, the compiler cannot determine the number that will be entered by the user, the error goes undetected. At runtime, the statement float Result = I / J; raises the DivideByZero exception, if the user enters 0 as the input for the second variable.

Logical Errors are those where the application compiles and runs properly but does not produce the required output, i.e errors in the logic of the program. They are harder to detect because they don’t throw any kind of exception. The best way to deal through them is to use the debugger, watches and call stacks.

Exceptions

System.Exception is the base class for all other exceptions. Below this level are the System.ApplicationException and System.SystemException classes which are derived from the System.Exception class.

The SystemException class acts as the base class for all the pre-defined Exceptions. ApplicationException class is to be used for any custom exceptions that you are to create in your application. Unlike the System Exceptions, these are forwarded by the application and not the CLR.

Below is a table listing some of the classes dervied from SystemException class.

Exception Class Description
System.IO.IOException Handles Input/Output errors
System.IndexOutOfRangeException Handles errors generated when a method refers to an array element, which is out of its bound.
System.NullReferenceException Hanldes errors generated during the process of dereferencing a null object.
System.DivideByZeroException Handles errors generated during the process of dividing a number by zero.
InvalidCastException Handles errors generated during typecasting.
OutOfMemoryException Handles memory allocation to the application errors.
Handling Exceptions

Exceptions are handled by using exception handlers. These exception handlers divide the code in blocks.

The try Block

All the codes that have a chance of throwing exceptions are put inside the Try block. Given below is a simple try block code.

try
{
    //Statements that may throw exceptions.
}

The catch Block

If any statement inside the try block throws an exception, the execution control is passed onto the appropriate catch block. This allows the application to recover from exceptions. Catch block follows the following syntax:-

catch (…)
{
//Error Handling Code
}

Note: Every try block must have an associated catch block and vice versa.

The following code would trap the exception thrown in the previous example.

try
{
    float Result = I / J;
}
catch
{
    Console.WriteLine("An error occured while trying to compute the result");
}

Whenever the user enters a value of 0 for J, an exception would be thrown. Since, this code is contained in a try block, the code inside the catch block will be executed and a message An error occured while trying to compute the result will be shown to the user.

In the above example, the type of exception being thrown is unknown. So, no matter what exception is thrown, the same message will be displayed.

You can specify the type of exception a catch block handles in the following way:-

try
{
    Result = Convert.ToInt32(I / J);
}
catch (DivideByZeroException)
{
    Console.WriteLine("You tried to divide the number by zero");
}

The catch block declaration can also instantiate an object of the corresponding Exception class providing access to exception specific information – Error Codes, Description, etc.

try
{
    Result = Convert.ToInt32(I / J);
}
catch (DivideByZeroException ex)
{
    Console.WriteLine(ex.Message);
}

The code given below is a modified form of the earlier example.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Console.WriteLine("Enter Two Numbers:-");
int I = Convert.ToInt32(Console.ReadLine());
double J = Convert.ToDouble(Console.ReadLine());
int Result = 0;
try
{
    Result = Convert.ToInt32(I / J);
}
catch
{
    Console.WriteLine("An error occured while trying to compute the result");
}
Console.WriteLine("The result is {0}", Result);
Console.Read();

Line 8 can now generate two types of exception: DivieByZeroException and OverflowException. When the user enters a very high value, say 65536275 for the variable I and an extremely low value, say 0.0000001 for J. The result would exceed the range of the int datatype and the OverflowException would be thrown. Because the user would be treated with the same error message, he/she might not be able to determine the exact cause of the error.

This is where the catch block comes in handy. Multiple catch blocks can be attached to a try block. Each of them should differ in the type of exception they handle.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Console.WriteLine("Enter Two Numbers:-");
int I = Convert.ToInt32(Console.ReadLine());
double J = Convert.ToDouble(Console.ReadLine());
int Result = 0;
try
{
    Result = Convert.ToInt32(I / J);
}
catch (DivideByZeroException)
{
 
    Console.WriteLine("You tried to divide the number by zero");
}
catch (OverflowException)
{
    Console.WriteLine("The operation resulted in an overflow");
}
catch(Exception)
{
    Console.WriteLine("An error occured while trying to compute the result");
}
Console.WriteLine("The result is {0}", Result);
Console.Read();

Now, if an OverflowException is thrown, the message The operation resulted in an overflow will be displayed. For the DivideByZero exception, the message You tried to divide the number by zero will be shown. For any other exception, the last message An error occured while trying to compute the result will be displayed.

Order of Catch Blocks

1
2
3
4
5
6
7
8
9
10
11
12
13
int A = 5, B = 0;
try
{
    A = A / B;
}
catch (Exception ex)
{
    Console.Write("Exception");
}
catch (DivideByZeroException ex)
{
    Console.Write("Divide By Zero Exception");
}

The order of the catch block is very important.

A series of catch statements needs to be in decreasing order of derivation. For example, the most derived objects must appear first.

The above code generates the following compile-error: A previous catch clause already catches all exceptions of this or of a super type (‘System.Exception’).

If the catch(Exception) block is declared at the top, even a DivideByZeroException or the OverflowException will be handled by this block. This is because both of them are indirectly derived from the Exception class. Infact, C# does not allow such scenarios. So, you must first declare the exception class that is at a deeper level of the hierarchy.

The correct code would be as follows:-

1
2
3
4
5
6
7
8
9
10
11
12
13
int A = 5, B = 0;
try
{
    A = A / B;
}
catch (DivideByZeroException ex)
{
    Console.Write("Divide By Zero Exception");
}
catch (Exception ex)
{
    Console.Write("Exception");
}

The finally block
This block is used to execute statements which are to be executed regardless of whether the exception is thrown or not. This may include a code such as to close a file, an existing SQL connection, etc. Only one finally block can exist for a try block. Also, the finally block is optional.

One may argue as to why we need the finally block because all statements below the entire try – catch block will be executed, irrespective of whether an exception is thrown or not. However, the code in the finally block is executed, even if a return statement is encountered inside the try or the catch block. The same is not true for the codes following the try – catch block.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
int I = 10, J = 0;
 
float Result = 0;
try
{
    Result = I / J;
}
catch
{
    Console.WriteLine("An error occured while trying to compute the result");
    return;
}
Console.WriteLine("The result is {0}", Result);
Console.Read();

The output of the preceeding block of code would be:-

An error occured while trying to compute the result

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int I = 10, J = 0;
 
float Result = 0;
try
{
    Result = I / J;
}
catch
{
    Console.WriteLine("An error occured while trying to compute the result");
    return;
}
finally
{
    Console.WriteLine("The result is {0}", Result);
    Console.Read();
}

While, the output for this one would be:-

An error occured while trying to compute the result
The result is 0

Creating Custom Exceptions

User defined exceptions can be created by deriving from the System.ApplicationException class or from any other system defined class. You can also derive Exceptions from these user-defined classes. The ultimate thing is that the new Exception class should be derived (directly or indirectly) from the Exception class.

1
2
3
4
5
6
7
class MyException : ApplicationException
{
    public MyException(string Message) : base(Message)
    {
 
    }
}
Raising Exceptions

Use the throw statement to raise your exceptions. This process requires the creation of a new object of the appropriate Exception class.

throw new(MyException("My Exception was thrown"));

Even the system defined exceptions can be thrown in this fashion.

Never create and throw an object of System.Exception class

C#

C# Tutorial : Lesson 14 – File Handling

October 17th, 2007
Files & Folders

One of the ways of permanent storage of data is through files. A file is a collection of data stored on a secondary storage device, such as the Hard Disk. Every file has a name associated with it, such as Essay.txt. The name comprises of two parts the base name (in our case ‘Essay’) and the extension (txt). The portion before the period (.) is the base name whereas the one after it is the extension. A file name can also contain multiple periods – Dr. No.avi. The most significant period is always the last one. So, in this case, the base name of the file would be Dr. No and the extension avi.

The extension is what determines the type of the file. For example, a document has an extension of doc while a JPEG Image file has an extension of jpg. The base name is what we specify to identify that particular file.

Files are contained in folders or directories. A directory itself can contain other files and folders, thus forming a hierarchy. Files within a folder (directory) need to have unique names. Files with same base name but different extensions are allowed. So, the file My File.txt and My File.doc can co-exist in a folder. The full path of the file marks its complete address on a machine. For instance, if the file Notepad.exe is contained inside the Windows directory of your C drive, its path would be “C:\Windows\Notepad.exe”. Likewise, if it were to be contained inside the System32 directory which in turn is present in the Windows directory, the full path would be “C:\Windows\System32\Notepad.exe”.

Note: No two files on your computer can have the same full path.

Stream

A stream is a sequence of bytes travelling from a source to a destination over a communication medium. Streams can either be input or output. The input stream is used for reading while the output stream is used for writing.

Note: This stream concept does not just apply to files. It holds true for communication over a network through sockets too.

File System Classes

.NET provides a lot of classes for handling files. These are contained in the System.IO namespace. Listed below are various classes under this namespace.

Class Name Description
FileStream Is used to read from and write to any location within a file.
BinaryReader Is used to read primitive data types in the form of binary data from the stream.
StreamReader Is used to read characters from a byte stream.
StringReader Is used to read data from a string buffer.
BinaryWriter Is used to write primitive data types in the form of binary data to the stream.
StreamWriter Is used to write characters to a byte stream.
StringWriter Is used to write data to a string buffer.
BinaryReader Is used to read primitive data types in the form of binary data from the file stream.
StreamReader Is used to read characters from the a byte stream.
DirectoryInfo Is used to perform operations on directories.
FileInfo Is used to perform operations on files.
FileStream Class

The FileStream class resides under the System.IO namespace and is derived from the abstract class Stream. It supports random access through seeking. Before you begin reading from and writing to a file, an object of the FileStream class needs to initialized. The parameterized constructor of this class allows to create/open files and set up appropriate file sharing modes.

Creating a new file.

FileStream fs = new FileStream
    (
        "TestFile.txt",
        FileMode.Create,
        FileAccess.Write,
        FileShare.Read
    );

Note: The code is spanned across multiple lines for the sake of clarity.

The first parameter to the constructor is the path to the file. In this case the new file will be created in the working directory of the application. A complete path such as C:\Program Files\Maxotek\Tutorials\C-Sharp\Lesson14\TestFile.txt can also be used. Backslash being the escape sequence starter would need to be escaped in the string. The code would look something like:-

FileStream fs = new FileStream
    (
        "C:\\Program Files\\Maxotek\\Tutorials\\C-Sharp\\Lesson14\\TestFile.txt",
        FileMode.Create,
        FileAccess.Write,
        FileShare.Read
    );

Another way of doing this, is to use the @ character before the string. This prevents any escape sequence character as the backslash itself is taken as a normal character.

FileStream fs = new FileStream
    (
        @"C:\Program Files\Maxotek\Tutorials\C-Sharp\Lesson14\TestFile.txt",
        FileMode.Create,
        FileAccess.Write,
        FileShare.Read
    );

The second parameter to the constructor is the FileMode enumeration. It can have any of the following values.

File Mode Description
Create Creates a new file or truncates the existing file.
CreateNew Creates a new file. If the file already exists, throws a System.IO.IOException.
Open Opens an existing file. Throws a System.IO.FileNotFoundException if the file does not exist.
OpenOrCreate Opens an existing file or creates a new one. The difference between this mode and the Create mode is that it does not truncate the file.
Append Opens the file and seeks to the end. A new file is created if the file does not exist.
Truncate Opens an existing file and truncates its content so that the file size becomes zero. Attempting to read in this mode throws an exception.

The third parameter is the FileAccess which specifies whether the file is to be opened for Reading (FileAccess.Read), Writing (FileAccess.Write) or both (FileAccess.ReadWrite).

The last parameter is FileShare mode which states how the file will be shared.

FileShare Mode Description
Read Allows other handles to read from the file.
Write Allows other handles to write to the file.
Delete Allows subsequent deleting of the file.
Inheritable Makes the file handle inheritable to child processes.
None Declines sharing of file. No other process can open the file until it is closed.

Note: The constructor is overloaded into many other forms which take various other types and combinations of parameters. The above form was one of the basic ones.

Writing to the File

We use the StreamWriter class which is inherited from the abstract class TextWriter to write a series of characters. After opening the file in the appropriate mode (Write or ReadWrite in this case), a new object of the StreamWriter class is created. The object of the FileStream class is passed to it, thus associating the stream with the file. After this, the content can be written to the file by using the Write or the WriteLine method. WriteLine appends an end of line to the content. These two methods are highly overloaded to enable almost all built in data types to be directly written.

Once you have done all the writing, make sure you close the file using the Close method. This ensures all the content is physically written to the file. For performance reasons, the write operation is buffered and sometimes the content might not be physically written to the file even after the Write method was called. To force all the buffers to be cleared and all buffered content to be written to the underlying stream (File in our case), use the Flush method.

1
2
3
4
5
6
7
8
9
10
11
12
FileStream fs = new FileStream
    (
        "TestFile.txt",
        FileMode.Create,
        FileAccess.Write,
        FileShare.Read
    );
StreamWriter sw = new StreamWriter(fs);
sw.Write("Hello World");
 
sw.Close();     // Close the Stream
fs.Close();     // Close the File

Reading from a fie

The StreamReader class is used to read a series of characters from a FilStream. This class is derived from the abstract class TextReader. Before reading, the file must be opened in the appropriate mode (Read or ReadWrite). To Read the next character or the next set of characters, use the Read method. This method has two forms. One that does not take any parameters and reads the next character. It returns the byte value of the character. The other one takes three parameters:-

  • An array of characters – The read characters are stored in the variable passed here.
  • The index of the buffer at which to begin writing
  • Maximum number of characters to read

The ReadLine method reads a line of characters and returns the result in the form of a string.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
FileStream fs = new FileStream
    (
        "TestFile.txt",
        FileMode.Open,
        FileAccess.Read,
        FileShare.Read
    );
 
StreamReader sr = new StreamReader(fs);
string str = sr.ReadLine();
while (str != null)
{
    Console.WriteLine(str);
    str = sr.ReadLine();
}
 
sr.Close();     // Close the Stream
fs.Close();     // Close the File

The file pointer can be seeked to any position of the file using the BaseStream property’s Seek method. This method takes two parameters. The first, a byte offset relative to the Origin (second) parameter. This value can be either positive which moves the pointer down the file or negative which moves the file pointer upwards. The second parameter known as the Origin parameter indicates the reference point to obtain the new position. The permissible values are Begin, Current and End.

The following line of code moves the file pointer to the 5th character from the beginning.

sr.BaseStream.Seek(5, SeekOrigin.Begin);

Moves the pointer to the start.

sr.BaseStream.Seek(0, SeekOrigin.Begin);

Moves the pointer to 5 characters ahead of the current position.

sr.BaseStream.Seek(5, SeekOrigin.Current);

Moves the pointer 5 characters backward from the current position.

sr.BaseStream.Seek(-5, SeekOrigin.Begin);

Moves the pointer to the end.

sr.BaseStream.Seek(0, SeekOrigin.End);

The Peek method is used to read the next character without consuming it, i.e the file pointer does not move ahead.

Implementing Binary Read & Write

The StreamReader and StreamWriter classes work with character data. In this mode everything is written as plain text. To implement binary operations, wherein a number such as 327.68 would be written as a float value consuming four bytes and not just as plain text, we need to use the BinaryReader and BinaryWriter classes.

They are very similar to their text counterparts except that no Line (ReadLine and WriteLine) methods are provided. The BinaryReader class also supports data type specific methods such as ReadInt32, ReadDouble, etc. These allow you to directly read the content from the file in the appropriate format. If we were to use the StreamReader class, we would have to convert the string to integer or double format using the Convert.ToInt32 and Convert.ToDouble methods.

Writing to File

1
2
3
int MyNumber = 69;
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(MyNumber);

Reading from file

1
2
BinaryReader br = new BinaryReader(fs);
int MyNumber = br.ReadInt32();
Implementing the Windows File System

Often we need to browse directories and locate files. Many such operations can be accomplished by using the two classes – DirectoryInfo and FileInfo. Both of these are derived from the FileSystemInfo class.

The tables below list some of the commonly used properties and methods corresponding to both of these classes.

Properties of DirectoryInfo Class

Property Description
Attributes Gets or sets attributes associated with the current directory.
CreationTime Gets or sets the Creation time of the directory.
Exists Gets a Boolean value indicating whether the directory exists
FullName Gets a string containing the full path of the directory.
LastAccessTime Gets the last accessed time of the directory.
Name Gets a string containing the name of the directory.

Methods of DirectoryInfo Class

Method Description
Create Creates a directory.
Delete Deletes a directory.
GetDirectories Returns the directories in the current directory. Supports filtering and recursive listing.
GetFiles Returns the file in the current directory.

Properties of FileInfo class

Property Description
Attributes Gets or sets the attributes associated with the current file.
CreationTime Gets or sets the CreationTime of the file.
Directory Gets an instance of the directory to which the file belongs to.
Exists Gets a Boolean value indicating whether the file exists.
Extension Gets a string containing the extension of the file.
FullName Gets a string containing the full path to the file.
LastAccessTime Gets the last access time of the file.
LastWriteTime Gets the time of the last wriiten activity on the file.
Length Gets the length of the file in Bytes.
Name Gets the name of the File.

Methods of FileInfo class

Method Description
Create Creates a new file.
AppendText Appends a text to the file.
Delete Deletes the file.
Open Opens the file.
OpenRead Opens a file in the read-only mode.
Creating Objects

Creating a DirectoryInfo or FileInfo object is very simple. The constructor takes the path to the file.

DirectoryInfo di = new DirectoryInfo("C:\\Windows");
FileInfo fi = new FileInfo("C:\\Windows\\Notepad.exe");
Listing All Files in a Directory

The following code snippet lists all the files in the C:\Windows directory.

1
2
3
4
5
6
DirectoryInfo di = new DirectoryInfo("C:\\Windows");
FileInfo[] fis = di.GetFiles();
foreach (FileInfo fi in fis)
{
    Console.WriteLine(fi.Name);
}

C#

C# Tutorial : Lesson 13 – Inheritance – Part II

October 14th, 2007
Abstract Class

Consider the term Vehicle. It does not have an existence of its own. However, types of vehicles; namely, Car, Aeroplane, Bus, etc do. Similarly, we can have Abstract classes which cannot be instantiated thus exhibiting the abstract behavior. They merely contain the skeleton of the class but not its implementation. The abstract keyword is used to declare such a class.

1
2
3
4
5
6
7
8
9
10
abstract class Vehicle
{
 
}
 
static void Main(string[] args)
{
    // Abstract Class cannot be instantiated
    Vehicle obj = new Vehicle();    // Shows Compilation Error.
}
Abstract Methods

Abstract methods contain the function signature and return type, but no body. A child class can override the abstract method thus providing its implementation. Abstract methods are also declared by using the abstract keyword.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
abstract class Vehicle
{
    public abstract void Run();
}
 
class Car : Vehicle
{
    public override void Run()
    {
        Console.WriteLine("Run the Car");
    }
}
 
class Bus : Vehicle
{
    public override void Run()
    {
        Console.WriteLine("Run the Bus");
    }
}

In this example, the abstract method Run() is declared in the Vehicle class. Notice the lack of the { } braces which marks the lack of a body. Since the Vehicle class cannot be instantiated, it does not need to have an implementation for the Run() method. The actual implementation is contained in its derived classes – Car, Bus. Thus, the abstract class only forms the skeleton of the child classes which exhibit specialization by overriding and implementing the abstract methods.

Note: Abstract methods can only be defined inside an abstract class.

Overriding Methods

In the previous example the override keyword is used. A parent class method can be overridden by a child class. In this way it provides its own implementation shadowing the one of the base class. A method must be declared as abstract or virtual to be overridden inside the child class.

Virtual Functions

The difference between a virtual function/method and an abstract method is that while the latter does not provide an implementation, the former does. If a virtual function of the parent class is not overridden, the method is inherited as it is, inside the child class. Again, we use the virtual keyword for declaring virtual functions.

The following example shows various cases when a method can/cannot be overridden.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
abstract class Vehicle
{
    // Abstract Method. Contains no body.
    public abstract void Run();
}
 
class Car : Vehicle
{
    // Abstract method is overridden.
    public override void Run()
    {
        Console.WriteLine("Run the Car");
    }
 
    // Normal Method. Cannot be overridden.
    public void Brake()
    {
        Console.WriteLine("Stop the Car");
    }
 
    // Virtual Method. Can be overridden.
    public virtual void Accelerate()
    {
        Console.WriteLine("Step on the gas");
    }
}
 
class BMW : Car
{
    // An overridden method can be further overridden.
    public override void Run()
    {
        Console.WriteLine("Run the BMW");
    }
 
    // Shows Compilation Error.
    // The Brake method of Car is
    // not declared as virtual or abstract.
    public override void Brake()
    {
        Console.WriteLine("Stop the Car");
    }
 
    // Virtual method is overridden.
    public override void Accelerate()
    {
        Console.WriteLine("Step on the gas");
    }
}

From the following you can deduce that for a method to be overridden, it must be declared as abstract or virtual. An overridden method can be further overridden because it carries over the virtual modifier.

Sealed Classes

So many ways to modify a class but none to protect? Fear not, sealed classes are here to the rescue. This modifier prevents a class from being tampered by not allowing other classes to inherit from it.

1
2
3
4
5
6
7
8
9
10
sealed class Ferari
{
 
}
 
// Shows Error. Cannot inherit from sealed class.
class McLaren : Ferari
{
 
}
Sealed Methods

Use the sealed modifier to prevent a method from being overridden. Normally, you do not need to use this modifier as the methods are not overridable by default. However, if you want to protect an overridden method from being further overridden, you should use the sealed method instead of sealing off the entire class.

Interfaces

Remember that C# does not support multiple inheritance? Multiple inheritance tends to cause more problems than it solves. However, the ability to derive methods and properties from multiple sources is present in C#. This is done using Interfaces. Interfaces only contain the declaration part of a class. The actual definition which comprises of the body of the method is present inside the class which implements the interface.

Declaring Interfaces

They are declared similar to how classes are. Only differences are that they can only contain methods and properties (no variables), they do not contain the definition for these methods/properties and off-course the interface keyword.

interface Flyer
{
	public void Fly();
}
Implementing Interfaces

Classes do not inherit from interfaces, rather implement them. Although, the process of doing this is the same.

class Aeroplane : Flyer
{
 
}

Multiple interfaces can be implemented as follows:-

class Aeroplane : Flyer, Vehicle
{
 
}

Here, Vehicle is also assumed to be an interface.

A class can inherit from another class and implement an interface in a similar fashion:-

class Bird : Mammal, Flyer
{
 
}

Note: Mammal is a class here.

Inheriting Interfaces

Interfaces themselves can inherit from other interfaces. Again, the process is the same.

interface MechanicalFlyer : Flyer
{
 
}
Why use interfaces?

Interfaces provide the skeletal structure of the classes which implement them. They separate the definition of objects from their implementation.

Why not just use Abstract classes?

Abstract classes are meant to be used when you want only some of the methods/properties to be implemented by the sub class. Besides, a class cannot inherit from multiple classes but it can implement multiple interfaces.

The following example depicts the need for interfaces.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
abstract class Animal
{
	public void Eat()
	{
	}
}
 
abstract class Vehicle
{
	public void Run()
	{
	}
}
 
interface Flyer
{
	public void Fly();
}
 
class Aeroplane : Vehicle, Flyer
{
 
}
 
class Bird : Animal, Flyer
{
 
}

As you can see, the two sub classes Bird and Aeroplane derive from the Animal and Vehicle classes respectively. Both have the characteristics of their respective base classes. The Bird like any other animal, eats while the Aeroplane being a vehicle, runs. However, they both share a common trait – the ability to fly. This ability is neither possessed by all animals nor by all vehicles. So it cannot be defined in either of the base classes. Again, it is not only possessed by the Aeroplane and Bird, some insects, baloons and other types of vehicles such as the Helicopter also possess it. It wouldn’t be effective to define this ability in each of them. Actually, it will be defined individually in each of these classes because each have their own way of flying, the bird flaps the wings, whereas the helicopter roatates its through a mechanical engine. However, this ability is declared in the Flyer interface so that any class which implements this interface would have to define the Fly() method by overriding it.

C#

The Necklace Problem

October 4th, 2007

An interesting problem in number theory is sometimes called the Necklace Problem. This problem begins with two single-digit numbers. The next number is obtained by adding the first two numbers together and saving only the ones digit. This process is repeated until the necklace closes by returning to the original two numbers. For example, if the starting two numbers are 1 and 8, twelve steps are required to close the necklace: 1 8 9 7 6 3 9 2 1 3 4 7 1 8.

Create a Necklace application that prompts the user for two single-digit integers and then displays the sequence and the number of steps taken.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
using System;
 
namespace Necklace_Problem
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.Write("Enter the First Number:");
            int Num1 = Convert.ToInt32(Console.ReadLine());
 
            Console.Write("Enter the Second Number:");
            int Num2 = Convert.ToInt32(Console.ReadLine());
 
            Console.WriteLine("Output = {0}", Necklace(Num1, Num2));
            Console.Read();
        }
 
        private static string Necklace(int OrigFirstNum, int OrigSecNum)
        {
            string Output = "";
 
            int FirstNum = OrigFirstNum;
            int SecondNum = OrigSecNum;
 
            Output = OrigFirstNum + " " + OrigSecNum + " ";
            do
            {
                int Result = FirstNum + SecondNum;
                int LastDigit = Result % 10;
                FirstNum = SecondNum;
                SecondNum = LastDigit;
                Output += SecondNum + " ";
            } while (!(FirstNum == OrigFirstNum && SecondNum == OrigSecNum));
 
            return Output;
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
Namespace Necklace_Problem
    Class Program
        Private Shared Sub Main(ByVal args As String())
            Console.Write("Enter the First Number:")
            Dim Num1 As Integer = Convert.ToInt32(Console.ReadLine())
 
            Console.Write("Enter the Second Number:")
            Dim Num2 As Integer = Convert.ToInt32(Console.ReadLine())
 
            Console.WriteLine("Output = {0}", Necklace(Num1, Num2))
            Console.Read()
        End Sub
 
        Private Shared Function Necklace(ByVal OrigFirstNum As Integer, ByVal OrigSecNum As Integer) As String
            Dim Output As String = ""
 
            Dim FirstNum As Integer = OrigFirstNum
            Dim SecondNum As Integer = OrigSecNum
 
            Output = OrigFirstNum + " " + OrigSecNum + " "
            Do
                Dim Result As Integer = FirstNum + SecondNum
                Dim LastDigit As Integer = Result Mod 10
                FirstNum = SecondNum
                SecondNum = LastDigit
                Output += SecondNum + " "
            Loop While Not (FirstNum = OrigFirstNum AndAlso SecondNum = OrigSecNum)
 
            Return Output
        End Function
    End Class
End Namespace

Recreational Mathematics