C# - 運算符
An operator is a symbol that tells the compiler to perform specific mathematical or logical manipulations. C# is rich in built-in operators and provides the following type of operators:
-
Arithmetic Operators
-
Relational Operators
-
Logical Operators
-
Bitwise Operators
-
Assignment Operators
-
Misc Operators
This tutorial will explain the arithmetic, relational, and logical, bitwise, assignment and other operators one by one.
算術運算符
Following table shows all the arithmetic operators supported by C#. Assume variable A holds 10 and variable B holds 20 then:
Operator | Description | Example |
---|---|---|
+ | Adds two operands | A + B will give 30 |
- | Subtracts second operand from the first | A - B will give -10 |
* | Multiply both operands | A * B will give 200 |
/ | Divide numerator by de-numerator | B / A will give 2 |
% | Modulus Operator and remainder of after an integer division | B % A will give 0 |
++ | Increment operator increases integer value by one | A++ will give 11 |
-- | Decrement operator decreases integer value by one | A-- will give 9 |
關係運算符
下表顯示了C#所支持的所有關係運算符。假設變量A持有10和變量B持有20:
Operator | Description | Example |
---|---|---|
== | Checks if the value of two operands is equal or not, if yes then condition becomes true. | (A == B) is not true. |
!= | Checks if the value of two operands is equal or not, if values are not equal then condition becomes true. | (A != B) is true. |
> | Checks if the value of left operand is greater than the value of right operand, if yes then condition becomes true. | (A > B) is not true. |
< | Checks if the value of left operand is less than the value of right operand, if yes then condition becomes true. | (A < B) is true. |
>= | Checks if the value of left operand is greater than or equal to the value of right operand, if yes then condition becomes true. | (A >= B) is not true. |
<= | Checks if the value of left operand is less than or equal to the value of right operand, if yes then condition becomes true. | (A <= B) is true. |
邏輯運算符
Following table shows all the logical operators supported by C#. Assume variable A holds Boolean value true and variable B holds Boolean value false then:
Operator | Description | Example |
---|---|---|
&& | Called Logical AND operator. If both the operands are non zero then condition becomes true. | (A && B) is false. |
|| | Called Logical OR Operator. If any of the two operands is non zero then condition becomes true. | (A || B) is true. |
! | Called Logical NOT Operator. Use to reverses the logical state of its operand. If a condition is true then Logical NOT operator will make false. | !(A && B) is true. |
位運算符
Operator | Description | Example |
---|---|---|
& | Binary AND Operator copies a bit to the result if it exists in both operands. | (A & B) will give 12 which is 0000 1100 |
| | Binary OR Operator copies a bit if it exists in either operand. | (A | B) will give 61 which is 0011 1101 |
^ | Binary XOR Operator copies the bit if it is set in one operand but not both. | (A ^ B) will give 49 which is 0011 0001 |
~ | Binary Ones Complement Operator is unary and has the effect of 'flipping' bits. | (~A ) will give -60 which is 1100 0011 |
<< | Binary Left Shift Operator. The left operands value is moved left by the number of bits specified by the right operand. | A << 2 will give 240 which is 1111 0000 |
>> | Binary Right Shift Operator. The left operands value is moved right by the number of bits specified by the right operand. | A >> 2 will give 15 which is 0000 1111 |
賦值運算符
There are following assignment operators supported by C#:
Operator | Description | Example |
---|---|---|
= | Simple assignment operator, Assigns values from right side operands to left side operand | C = A + B will assign value of A + B into C |
+= | Add AND assignment operator, It adds right operand to the left operand and assign the result to left operand | C += A is equivalent to C = C + A |
-= | Subtract AND assignment operator, It subtracts right operand from the left operand and assign the result to left operand | C -= A is equivalent to C = C - A |
*= | Multiply AND assignment operator, It multiplies right operand with the left operand and assign the result to left operand | C *= A is equivalent to C = C * A |
/= | Divide AND assignment operator, It divides left operand with the right operand and assign the result to left operand | C /= A is equivalent to C = C / A |
%= | Modulus AND assignment operator, It takes modulus using two operands and assign the result to left operand | C %= A is equivalent to C = C % A |
<<= | Left shift AND assignment operator | C <<= 2 is same as C = C << 2 |
>>= | Right shift AND assignment operator | C >>= 2 is same as C = C >> 2 |
&= | Bitwise AND assignment operator | C &= 2 is same as C = C & 2 |
^= | bitwise exclusive OR and assignment operator | C ^= 2 is same as C = C ^ 2 |
|= | bitwise inclusive OR and assignment operator | C |= 2 is same as C = C | 2 |
Misc Operators
There are few other important operators including sizeof, typeof and ? : supported by C#.
Operator | Description | Example |
---|---|---|
sizeof() | Returns the size of a data type. | sizeof(int), will return 4. |
typeof() | Returns the type of a class. | typeof(StreamReader); |
& | Returns the address of an variable. | &a; will give actual address of the variable. |
* | Pointer to a variable. | *a; will pointer to a variable. |
? : | Conditional Expression | If Condition is true ? Then value X : Otherwise value Y |
is | Determines whether an object is of a certain type. | If( Ford is Car) // checks if Ford is an object of the Car class. |
as | Cast without raising an exception if the cast fails. |
Object obj = new StringReader("Hello"); StringReader r = obj as StringReader; |
C#運算符優先級
Operator precedence determines the grouping of terms in an expression. This affects how an expression is evaluated. Certain operators have higher precedence than others; for example, the multiplication operator has higher precedence than the addition operator:
For example x = 7 + 3 * 2; Here x is assigned 13, not 20 because operator * has higher precedence than + so it first get multiplied with 3*2 and then adds into 7.
Here operators with the highest precedence appear at the top of the table, those with the lowest appear at the bottom. Within an expression, higher precedence operators will be evaluated first.
Category | Operator | Associativity |
---|---|---|
Postfix | () [] -> . ++ - - | Left to right |
Unary | + - ! ~ ++ - - (type)* & sizeof | Right to left |
Multiplicative | * / % | Left to right |
Additive | + - | Left to right |
Shift | << >> | Left to right |
Relational | < <= > >= | Left to right |
Equality | == != | Left to right |
Bitwise AND | & | Left to right |
Bitwise XOR | ^ | Left to right |
Bitwise OR | | | Left to right |
Logical AND | && | Left to right |
Logical OR | || | Left to right |
Conditional | ?: | Right to left |
Assignment | = += -= *= /= %=>>= <<= &= ^= |= | Right to left |
Comma | , | Left to right |
C# - 決策
Decision making structures require that the programmer specify one or more conditions to be evaluated or tested by the program, along with a statement or statements to be executed if the condition is determined to be true, and optionally, other statements to be executed if the condition is determined to be false.
Following is the general from of a typical decision making structure found in most of the programming languages:
C# provides following types of decision making statements. Click the following links to check their detail.
Statement | Description |
---|---|
if statement | An if statement consists of a boolean expression followed by one or more statements. |
if...else statement | An if statement can be followed by an optional else statement, which executes when the boolean expression is false. |
nested if statements | You can use one if or else if statement inside another if or else if statement(s). |
switch statement | A switch statement allows a variable to be tested for equality against a list of values. |
nested switch statements | You can use one swicth statement inside another switch statement(s). |
C# - 循環
There may be a situation when you need to execute a block of code several number of times. In general statements are executed sequentially: The first statement in a function is executed first, followed by the second, and so on.
Programming languages provide various control structures that allow for more complicated execution paths.
A loop statement allows us to execute a statement or group of statements multiple times and following is the general from of a loop statement in most of the programming languages:
C# provides following types of loop to handle looping requirements. Click the following links to check their detail.
Loop Type | Description |
---|---|
while loop | Repeats a statement or group of statements until a given condition is true. It tests the condition before executing the loop body. |
for loop | Execute a sequence of statements multiple times and abbreviates the code that manages the loop variable. |
do...while loop | Like a while statement, except that it tests the condition at the end of the loop body |
nested loops | You can use one or more loop inside any another while, for or do..while loop. |
循環控製語句:
Loop control statements change execution from its normal sequence. When execution leaves a scope, all automatic objects that were created in that scope are destroyed.
C# provides the following control statements. Click the following links to check their detail.
Control Statement | Description |
---|---|
break statement | Terminates the loop or switch statement and transfers execution to the statement immediately following the loop or switch. |
continue statement | Causes the loop to skip the remainder of its body and immediately retest its condition prior to reiterating. |
C# - 封裝
Encapsulation is defined 'as the process of enclosing one or more items within a physical or logical package'. Encapsulation, in object oriented programming methodology, prevents access to implementation details.
Abstraction and encapsulation are related features in object oriented programming. Abstraction allows making relevant information visible and encapsulation enables a programmer to implement the desired level of abstraction.
Encapsulation is implemented by using access specifiers. An access specifier defines the scope and visibility of a class member. C# supports the following access specifiers:
-
Public
-
Private
-
Protected
-
Internal
-
Protected internal
公開訪問修辭符
Public access specifier allows a class to expose its member variables and member functions to other functions and objects. Any public member can be accessed from outside the class.
The following example illustrates this:
using System; namespace RectangleApplication { class Rectangle { //member variables public double length; public double width; public double GetArea() { return length * width; } public void Display() { Console.WriteLine("Length: {0}", length); Console.WriteLine("Width: {0}", width); Console.WriteLine("Area: {0}", GetArea()); } }//end class Rectangle class ExecuteRectangle { static void Main(string[] args) { Rectangle r = new Rectangle(); r.length = 4.5; r.width = 3.5; r.Display(); Console.ReadLine(); } } }
When the above code is compiled and executed, it produces following result:
Length: 4.5 Width: 3.5 Area: 15.75
In the preceding example, the member variables length and width are declared public, so they can be accessed from the function Main() using an instance of the Rectangle class, named r.
The member function Display() and GetArea() can also access these variables directly without using any instance of the class.
The member functions Display() is also declared public, so it can also be accessed from Main() using an instance of the Rectangle class, named r.
私人(private)訪修辭符
Private access specifier allows a class to hide its member variables and member functions from other functions and objects. Only functions of the same class can access its private members. Even an instance of a class cannot access its private members.
The following example illustrates this:
using System; namespace RectangleApplication { class Rectangle { //member variables private double length; private double width; public void Acceptdetails() { Console.WriteLine("Enter Length: "); length = Convert.ToDouble(Console.ReadLine()); Console.WriteLine("Enter Width: "); width = Convert.ToDouble(Console.ReadLine()); } public double GetArea() { return length * width; } public void Display() { Console.WriteLine("Length: {0}", length); Console.WriteLine("Width: {0}", width); Console.WriteLine("Area: {0}", GetArea()); } }//end class Rectangle class ExecuteRectangle { static void Main(string[] args) { Rectangle r = new Rectangle(); r.Acceptdetails(); r.Display(); Console.ReadLine(); } } }
When the above code is compiled and executed, it produces following result:
Enter Length: 4.4 Enter Width: 3.3 Length: 4.4 Width: 3.3 Area: 14.52
In the preceding example, the member variables length and width are declared private, so they cannot be accessed from the function Main(). The member functionsAcceptDetails() and Display() can access these variables. Since the member functions AcceptDetails() and Display() are declared public, they can be accessed from Main() using an instance of the Rectangle class, named r.
Protected Access Specifier
Protected access specifier allows a child class to access the member variables and member functions of its base class. This way it helps in implementing inheritance. We will discuss this in more details in the inheritance chapter.
內部訪問符
Internal access specifier allows a class to expose its member variables and member functions to other functions and objects in the current assembly. In other words, any member with internal access specifier can be accessed from any class or method defined within the application in which the member is defined.
The following program illustrates this:
using System; namespace RectangleApplication { class Rectangle { //member variables internal double length; internal double width; double GetArea() { return length * width; } public void Display() { Console.WriteLine("Length: {0}", length); Console.WriteLine("Width: {0}", width); Console.WriteLine("Area: {0}", GetArea()); } }//end class Rectangle class ExecuteRectangle { static void Main(string[] args) { Rectangle r = new Rectangle(); r.length = 4.5; r.width = 3.5; r.Display(); Console.ReadLine(); } } }
When the above code is compiled and executed, it produces following result:
Length: 4.5 Width: 3.5 Area: 15.75
In the preceding example, notice that the member function GetArea() is not declared with any access specifier. Then what would be the default access specifier of a class member if we don't mention any? It is private.
受保護的內部訪問符
The protected internal access specifier allows a class to hide its member variables and member functions from other class objects and functions, except a child class within the same application. This is also used while implementing inheritance.
C# - 方法
A method is a group of statements that together perform a task. Every C# program has at least one class with a method named Main.
To use a method, you need to:
-
Define the method
-
Call the method
Defining Methods in C#
When you define a method, you basically declare the elements of its structure. The syntax for defining a method in C# is as follows:
<Access Specifier> <Return Type> <Method Name>(Parameter List) { Method Body }
Following are the various elements of a method:
-
Access Specifier: This determines the visibility of a variable or a method from another class.
-
Return type: A method may return a value. The return type is the data type of the value the method returns. If the method is not returning any values, then the return type is void.
-
Method name: Method name is a unique identifier and it is case sensitive. It cannot be same as any other identifier declared in the class.
-
Parameter list: Enclosed between parentheses, the parameters are used to pass and receive data from a method. The parameter list refers to the type, order, and number of the parameters of a method. Parameters are optional; that is, a method may contain no parameters.
-
Method body: This contains the set of instructions needed to complete the required activity.
Example:
Following code snippet shows a function FindMax that takes two integer values and returns the larger of the two. It has public access specifier, so it can be accessed from outside the class using an instance of the class.
class NumberManipulator { public int FindMax(int num1, int num2) { /* local variable declaration */ int result; if (num1 > num2) result = num1; else result = num2; return result; } ... }
Calling Methods in C#
You can call a method using the name of the method. The following example illustrates this:
using System; namespace CalculatorApplication { class NumberManipulator { public int FindMax(int num1, int num2) { /* local variable declaration */ int result; if (num1 > num2) result = num1; else result = num2; return result; } static void Main(string[] args) { /* local variable definition */ int a = 100; int b = 200; int ret; NumberManipulator n = new NumberManipulator(); //calling the FindMax method ret = n.FindMax(a, b); Console.WriteLine("Max value is : {0}", ret ); Console.ReadLine(); } }
When the above code is compiled and executed, it produces following result:
Max value is : 200
C# - Nullables
C# provides a special data types, the nullable types, to which you can assign normal range of values as well as null values.
For example, you can store any value from -2,147,483,648 to 2,147,483,647 or null in a Nullable< Int32 > variable. Similarly, you can assign true, false or null in a Nullable< bool > variable. Syntax for declaring a nullable type is as follows:
< data_type> ? <variable_name> = null;
The following example demonstrates use of nullable data types:
using System; namespace CalculatorApplication { class NullablesAtShow { static void Main(string[] args) { int? num1 = null; int? num2 = 45; double? num3 = new double?(); double? num4 = 3.14157; bool? boolval = new bool?(); // display the values Console.WriteLine("Nullables at Show: {0}, {1}, {2}, {3}", num1, num2, num3, num4); Console.WriteLine("A Nullable boolean value: {0}", boolval); Console.ReadLine(); } } }
When the above code is compiled and executed, it produces following result:
Nullables at Show: , 45, , 3.14157 A Nullable boolean value:
The Null Coalescing Operator (??)
The null coalescing operator is used with the nullable value types and reference types. It is used for converting an operand to the type of another nullable( or not) value type operand, where an implicit conversion is possible.
If the value of the first operand is null, then the operator returns the value of the second operand, otherwise it returns the value of the first operand. The following example explains this:
using System; namespace CalculatorApplication { class NullablesAtShow { static void Main(string[] args) { double? num1 = null; double? num2 = 3.14157; double num3; num3 = num1 ?? 5.34; Console.WriteLine(" Value of num3: {0}", num3); num3 = num2 ?? 5.34; Console.WriteLine(" Value of num3: {0}", num3); Console.ReadLine(); } } }
When the above code is compiled and executed, it produces following result:
Value of num3: 5.34 Value of num3: 3.14157
C# - Arrays
An array stores a fixed-size sequential collection of elements of the same type. An array is used to store a collection of data, but it is often more useful to think of an array as a collection of variables of the same type.
Instead of declaring individual variables, such as number0, number1, ..., and number99, you declare one array variable such as numbers and use numbers[0], numbers[1], and ..., numbers[99] to represent individual variables. A specific element in an array is accessed by an index.
All arrays consist of contiguous memory locations. The lowest address corresponds to the first element and the highest address to the last element.
Declaring Arrays
To declare an array in C#, you can use the following syntax:
datatype[] arrayName;
where,
-
datatype is used to specify the type of elements to be stored in the array.
-
[ ] specifies the rank of the array. The rank specifies the size of the array.
-
arrayName specifies the name of the array.
For example,
double[] balance;
Initializing an Array
Declaring an array does not initialize the array in the memory. When the array variable is initialized, you can assign values to the array.
Array is a reference type, so you need to use the new keyword to create an instance of the array.
For example,
double[] balance = new double[10];
Assigning Values to an Array
You can assign values to individual array elements, by using the index number, like:
double[] balance = new double[10]; balance[0] = 4500.0;
You can assign values to the array at the time of declaration, like:
double[] balance = { 2340.0, 4523.69, 3421.0};
You can also create and initialize an array, like:
int [] marks = new int[5] { 99, 98, 92, 97, 95};
In the preceding case, you may also omit the size of the array, like:
int [] marks = new int[] { 99, 98, 92, 97, 95};
You can also copy an array variable into another target array variable. In that case, both the target and source would point to the same memory location:
int [] marks = new int[] { 99, 98, 92, 97, 95}; int[] score = marks;
When you create an array, C# compiler implicitly initializes each array element to a default value depending on the array type. For example for an int array all elements would be initialized to 0.
Accessing Array Elements
An element is accessed by indexing the array name. This is done by placing the index of the element within square brackets after the name of the array. For example:
double salary = balance[9];
Following is an example which will use all the above mentioned three concepts viz. declaration, assignment and accessing arrays:
using System; namespace ArrayApplication { class MyArray { static void Main(string[] args) { int [] n = new int[10]; /* n is an array of 10 integers */ int i,j; /* initialize elements of array n */ for ( i = 0; i < 10; i++ ) { n[ i ] = i + 100; } /* output each array element's value */ for (j = 0; j < 10; j++ ) { Console.WriteLine("Element[{0}] = {1}", j, n[j]); } Console.ReadKey(); } } }
When the above code is compiled and executed, it produces following result:
Element[0] = 100 Element[1] = 101 Element[2] = 102 Element[3] = 103 Element[4] = 104 Element[5] = 105 Element[6] = 106 Element[7] = 107 Element[8] = 108 Element[9] = 109
C# - Strings
In C# you can use strings as array of characters, however, more common practice is to use the string keyword to declare a string variable. The string keyword is an alias for theSystem.String class.
Creating a String Object
You can create string object using one of the following methods:
-
By assigning a string literal to a String variable
-
By using a String class constructor
-
By using the string concatenation operator (+)
-
By retrieving a property or calling a method that returns a string
-
By calling a formatting method to convert a value or object to its string representation
The following example demonstrates this:
using System; namespace StringApplication { class Program { static void Main(string[] args) { //from string literal and string concatenation string fname, lname; fname = "Rowan"; lname = "Atkinson"; string fullname = fname + lname; Console.WriteLine("Full Name: {0}", fullname); //by using string constructor char[] letters = { 'H', 'e', 'l', 'l','o' }; string greetings = new string(letters); Console.WriteLine("Greetings: {0}", greetings); //methods returning string string[] sarray = { "Hello", "From", "Tutorials", "Point" }; string message = String.Join(" ", sarray); Console.WriteLine("Message: {0}", message); //formatting method to convert a value DateTime waiting = new DateTime(2012, 10, 10, 17, 58, 1); string chat = String.Format("Message sent at {0:t} on {0:D}", waiting); Console.WriteLine("Message: {0}", chat); Console.ReadKey() ; } } }
When the above code is compiled and executed, it produces following result:
Full Name: Rowan Atkinson Greetings: Hello Message: Hello From Tutorials Point Message: Message sent at 5:58 PM on Wednesday, October 10, 2012
C# - Structures
In C#, a structure is a value type data type. It helps you to make a single variable hold related data of various data types. The struct keyword is used for creating a structure.
Structures are used to represent a record. Suppose you want to keep track of your books in a library. You might want to track the following attributes about each book:
-
Title
-
Author
-
Subject
-
Book ID
Defining a Structure
To define a structure, you must use the struct statement. The struct statement defines a new data type, with more than one member for your program.
For example, here is the way you would declare the Book structure:
struct Books { public string title; public string author; public string subject; public int book_id; };
The following program shows the use of the structure:
using System; struct Books { public string title; public string author; public string subject; public int book_id; }; public class testStructure { public static void Main(string[] args) { Books Book1; /* Declare Book1 of type Book */ Books Book2; /* Declare Book2 of type Book */ /* book 1 specification */ Book1.title = "C Programming"; Book1.author = "Nuha Ali"; Book1.subject = "C Programming Tutorial"; Book1.book_id = 6495407; /* book 2 specification */ Book2.title = "Telecom Billing"; Book2.author = "Zara Ali"; Book2.subject = "Telecom Billing Tutorial"; Book2.book_id = 6495700; /* print Book1 info */ Console.WriteLine( "Book 1 title : {0}", Book1.title); Console.WriteLine("Book 1 author : {0}", Book1.author); Console.WriteLine("Book 1 subject : {0}", Book1.subject); Console.WriteLine("Book 1 book_id :{0}", Book1.book_id); /* print Book2 info */ Console.WriteLine("Book 2 title : {0}", Book2.title); Console.WriteLine("Book 2 author : {0}", Book2.author); Console.WriteLine("Book 2 subject : {0}", Book2.subject); Console.WriteLine("Book 2 book_id : {0}", Book2.book_id); Console.ReadKey(); } }
When the above code is compiled and executed, it produces following result:
Book 1 title : C Programming Book 1 author : Nuha Ali Book 1 subject : C Programming Tutorial Book 1 book_id : 6495407 Book 2 title : Telecom Billing Book 2 author : Zara Ali Book 2 subject : Telecom Billing Tutorial Book 2 book_id : 6495700
C# - Enums
An enumeration is a set of named integer constants. An enumerated type is declared using the enum keyword.
C# enumerations are value data type. In other words, enumeration contains its own values and cannot inherit or cannot pass inheritance.
Declaring enum Variable
The general syntax for declaring an enumeration is:
enum <enum_name> { enumeration list };
Where,
-
The enum_name specifies the enumeration type name.
-
The enumeration list is a comma-separated list of identifiers.
Each of the symbols in the enumeration list stands for an integer value, one greater than the symbol that precedes it. By default, the value of the first enumeration symbol is 0. For example:
enum Days { Sun, Mon, tue, Wed, thu, Fri, Sat };
Example:
The following example demonstrates use of enum variable:
using System; namespace EnumApplication { class EnumProgram { enum Days { Sun, Mon, tue, Wed, thu, Fri, Sat }; static void Main(string[] args) { int WeekdayStart = (int)Days.Mon; int WeekdayEnd = (int)Days.Fri; Console.WriteLine("Monday: {0}", WeekdayStart); Console.WriteLine("Friday: {0}", WeekdayEnd); Console.ReadKey(); } } }
When the above code is compiled and executed, it produces following result:
Monday: 1 Friday: 5
C# - Classes
When you define a class, you define a blueprint for a data type. This doesn't actually define any data, but it does define what the class name means, that is, what an object of the class will consist of and what operations can be performed on such an object. Objects are instances of a class. The methods and variables that constitute a class are called members of the class.
Class Definition
A class definition starts with the keyword class followed by the class name; and the class body, enclosed by a pair of curly braces. Following is the general form of a class definition:
<access specifier> class class_name { // member variables <access specifier> <data type> variable1; <access specifier> <data type> variable2; ... <access specifier> <data type> variableN; // member methods <access specifier> <return type> method1(parameter_list) { // method body } <access specifier> <return type> method2(parameter_list) { // method body } ... <access specifier> <return type> methodN(parameter_list) { // method body } }
Please note that,
-
Access specifiers specify the access rules for the members as well as the class itself, if not mentioned then the default access specifier for a class type is internal. Default access for the members is private.
-
Data type specifies the type of variable, and return type specifies the data type of the data, the method returns, if any.
-
To access the class members, you will use the dot (.) operator.
-
The dot operator links the name of an object with the name of a member.
The following example illustrates the concepts discussed so far:
using System; namespace BoxApplication { class Box { public double length; // Length of a box public double breadth; // Breadth of a box public double height; // Height of a box } class Boxtester { static void Main(string[] args) { Box Box1 = new Box(); // Declare Box1 of type Box Box Box2 = new Box(); // Declare Box2 of type Box double volume = 0.0; // Store the volume of a box here // box 1 specification Box1.height = 5.0; Box1.length = 6.0; Box1.breadth = 7.0; // box 2 specification Box2.height = 10.0; Box2.length = 12.0; Box2.breadth = 13.0; // volume of box 1 volume = Box1.height * Box1.length * Box1.breadth; Console.WriteLine("Volume of Box1 : {0}", volume); // volume of box 2 volume = Box2.height * Box2.length * Box2.breadth; Console.WriteLine("Volume of Box2 : {0}", volume); Console.ReadKey(); } } }
When the above code is compiled and executed, it produces following result:
Volume of Box1 : 210 Volume of Box2 : 1560
Constructors in C#
A class constructor is a special member function of a class that is executed whenever we create new objects of that class.
A constructor will have exact same name as the class and it does not have any return type. Following example explains the concept of constructor:
using System; namespace LineApplication { class Line { private double length; // Length of a line public Line() { Console.WriteLine("Object is being created"); } public void setLength( double len ) { length = len; } public double getLength() { return length; } static void Main(string[] args) { Line line = new Line(); // set line length line.setLength(6.0); Console.WriteLine("Length of line : {0}", line.getLength()); Console.ReadKey(); } } }
When the above code is compiled and executed, it produces following result:
Object is being created Length of line : 6
Destructors in C#
A destructor is a special member function of a class that is executed whenever an object of its class goes out of scope. A destructor will have exact same name as the class prefixed with a tilde (~) and it can neither return a value nor can it take any parameters.
Destructor can be very useful for releasing resources before coming out of the program like closing files, releasing memories etc. Destructors cannot be inherited or overloaded.
Following example explain the concept of destructor:
using System; namespace LineApplication { class Line { private double length; // Length of a line public Line() // constructor { Console.WriteLine("Object is being created"); } ~Line() //destructor { Console.WriteLine("Object is being deleted"); } public void setLength( double len ) { length = len; } public double getLength() { return length; } static void Main(string[] args) { Line line = new Line(); // set line length line.setLength(6.0); Console.WriteLine("Length of line : {0}", line.getLength()); } } }
When the above code is compiled and executed, it produces following result:
Object is being created Length of line : 6 Object is being deleted
C# - Inheritance
One of the most important concepts in object-oriented programming is that of inheritance. Inheritance allows us to define a class in terms of another class, which makes it easier to create and maintain an application. This also provides an opportunity to reuse the code functionality and fast implementation time.
When creating a class, instead of writing completely new data members and member functions, the programmer can designate that the new class should inherit the members of an existing class. This existing class is called the base class, and the new class is referred to as the derived class.
The idea of inheritance implements the IS-A relationship. For example, mammal IS A animal, dog IS-A mammal hence dog IS-A animal as well and so on.
Base and Derived Classes
A class can be derived from more than one class or interface, which means that it can inherit data and functions from multiple base class or interface.
The syntax used in C# for creating derived classes is as follows:
<acess-specifier> class <base_class> { ... } class <derived_class> : <base_class> { ... }
Consider a base class Shape and its derived class Rectangle:
using System; namespace InheritanceApplication { class Shape { public void setWidth(int w) { width = w; } public void setHeight(int h) { height = h; } protected int width; protected int height; } // Derived class class Rectangle: Shape { public int getArea() { return (width * height); } } class RectangleTester { static void Main(string[] args) { Rectangle Rect = new Rectangle(); Rect.setWidth(5); Rect.setHeight(7); // Print the area of the object. Console.WriteLine("Total area: {0}", Rect.getArea()); Console.ReadKey(); } } }
When the above code is compiled and executed, it produces following result:
Total area: 35
C# - Polymorphism
The word polymorphism means having many forms. In object oriented programming paradigm, polymorphism is often expressed as 'one interface, multiple functions'.
Polymorphism can be static or dynamic. In static polymorphism the response to a function is determined at the compile time. In dynamic polymorphism it is decided at run time.
Static Polymorphism
The mechanism of linking a function with an object during compile time is called early binding. It is also called static binding. C# provides two techniques to implement static polymorphism. These are:
-
Function overloading
-
Operator overloading
We will discuss function overloading in the next section and operator overloading will be dealt with in next chapter.
Function Overloading
You can have multiple definitions for the same function name in the same scope. The definition of the function must differ from each other by the types and/or the number of arguments in the argument list. You cannot overload function declarations that differ only by return type.
Following is the example where same function print() is being used to print different data types:
using System; namespace PolymorphismApplication { class Printdata { void print(int i) { Console.WriteLine("Printing int: {0}", i ); } void print(double f) { Console.WriteLine("Printing float: {0}" , f); } void print(string s) { Console.WriteLine("Printing string: {0}", s); } static void Main(string[] args) { Printdata p = new Printdata(); // Call print to print integer p.print(5); // Call print to print float p.print(500.263); // Call print to print string p.print("Hello C++"); Console.ReadKey(); } } }
When the above code is compiled and executed, it produces following result:
Printing int: 5 Printing float: 500.263 Printing string: Hello C++
Dynamic Polymorphism
C# allows you to create abstract classes that are used to provide partial class implementation of an interface. Implementation is completed when a derived class inherits from it.Abstract classes contain abstract methods which are implemented by the derived class. The derived classes have more specialized functionality.
Please note the following rules about abstract classes:
-
You cannot create an instance of an abstract class
-
You cannot declare an abstract method outside an abstract class
-
When a class is declared sealed, it cannot be inherited, abstract classes cannot be declared sealed.
The following program demonstrates an abstract class:
using System; namespace PolymorphismApplication { abstract class Shape { public abstract int area(); } class Rectangle: Shape { private int length; private int width; public Rectangle( int a=0, int b=0) { length = a; width = b; } public override int area () { Console.WriteLine("Rectangle class area :"); return (width * length); } } class RectangleTester { static void Main(string[] args) { Rectangle r = new Rectangle(10, 7); double a = r.area(); Console.WriteLine("Area: {0}",a); Console.ReadKey(); } } }
When the above code is compiled and executed, it produces following result:
Rectangle class area : Area: 70
C# - Operator Overloading
You can redefine or overload most of the built-in operators available in C#. Thus a programmer can use operators with user-defined types as well. Overloaded operators are functions with special names the keyword operator followed by the symbol for the operator being defined. Like any other function, an overloaded operator has a return type and a parameter list.
For example, look at the following function:
public static Box operator+ (Box b, Box c) { Box box = new Box(); box.length = b.length + c.length; box.breadth = b.breadth + c.breadth; box.height = b.height + c.height; return box; }
The above function implements the addition operator (+) for a user-defined class Box. It adds the attributes of two Box objects and returns the resultant Box object.
Implementation of Operator Overloading
The following program shows the complete implementation:
using System; namespace OperatorOvlApplication { class Box { private double length; // Length of a box private double breadth; // Breadth of a box private double height; // Height of a box public double getVolume() { return length * breadth * height; } public void setLength( double len ) { length = len; } public void setBreadth( double bre ) { breadth = bre; } public void setHeight( double hei ) { height = hei; } // Overload + operator to add two Box objects. public static Box operator+ (Box b, Box c) { Box box = new Box(); box.length = b.length + c.length; box.breadth = b.breadth + c.breadth; box.height = b.height + c.height; return box; } } class Tester { static void Main(string[] args) { Box Box1 = new Box(); // Declare Box1 of type Box Box Box2 = new Box(); // Declare Box2 of type Box Box Box3 = new Box(); // Declare Box3 of type Box double volume = 0.0; // Store the volume of a box here // box 1 specification Box1.setLength(6.0); Box1.setBreadth(7.0); Box1.setHeight(5.0); // box 2 specification Box2.setLength(12.0); Box2.setBreadth(13.0); Box2.setHeight(10.0); // volume of box 1 volume = Box1.getVolume(); Console.WriteLine("Volume of Box1 : {0}", volume); // volume of box 2 volume = Box2.getVolume(); Console.WriteLine("Volume of Box2 : {0}", volume); // Add two object as follows: Box3 = Box1 + Box2; // volume of box 3 volume = Box3.getVolume(); Console.WriteLine("Volume of Box3 : {0}", volume); Console.ReadKey(); } } }
When the above code is compiled and executed, it produces following result:
Volume of Box1 : 210 Volume of Box2 : 1560 Volume of Box3 : 5400
Overloadable and Non-Overloadable Operators
The following table describes the overload ability of the operators in C#:
Operators | Description |
---|---|
+, -, !, ~, ++, -- | These unary operators take one operand and can be overloaded. |
+, -, *, /, % | These binary operators take one operand and can be overloaded. |
==, !=, <, >, <=, >= | The comparison operators can be overloaded |
&&, || | The conditional logical operators cannot be overloaded directly. |
+=, -=, *=, /=, %= | The assignment operators cannot be overloaded. |
=, ., ?:, ->, new, is, sizeof, typeof | These operators cannot be overloaded. |
C# - Interfaces
An interface is defined as a syntactical contract that all the classes inheriting the interface should follow. The interface defines the 'what' part of the syntactical contract and the deriving classes define the 'how' part of the syntactical contract.
Interfaces define properties, methods and events, which are the members of the interface. Interfaces contain only the declaration of the members. It is the responsibility of the deriving class to define the members. It often helps in providing a standard structure that the deriving classes would follow.
Abstract classes to some extent serve the same purpose, however, they are mostly used when only few methods are to be declared by the base class and the deriving class implements the functionalities.
Declaring Interfaces
Interfaces are declared using the interface keyword. It is similar to class declaration. Interface statements are public by default. Following is an example of an interface declaration:
public interface ITransactions { // interface members void showTransaction(); double getAmount(); }
Example
The following example demonstrates implementation of the above interface:
using System.Collections.Generic; using System.Linq; using System.Text; namespace InterfaceApplication { public interface ITransactions { // interface members void showTransaction(); double getAmount(); } public class Transaction : ITransactions { private string tCode; private string date; private double amount; public Transaction() { tCode = " "; date = " "; amount = 0.0; } public Transaction(string c, string d, double a) { tCode = c; date = d; amount = a; } public double getAmount() { return amount; } public void showTransaction() { Console.WriteLine("Transaction: {0}", tCode); Console.WriteLine("Date: {0}", date); Console.WriteLine("Amount: {0}", getAmount()); } } class Tester { static void Main(string[] args) { Transaction t1 = new Transaction("001", "8/10/2012", 78900.00); Transaction t2 = new Transaction("002", "9/10/2012", 451900.00); t1.showTransaction(); t2.showTransaction(); Console.ReadKey(); } } }
When the above code is compiled and executed, it produces following result:
Transaction: 001 Date: 8/10/2012 Amount: 78900 Transaction: 002 Date: 9/10/2012 Amount: 451900
C# - Namespaces
A namespace is designed for providing a way to keep one set of names separate from another. The class names declared in one namespace will not conflict with the same class names declared in another.
Defining a Namespace
A namespace definition begins with the keyword namespace followed by the namespace name as follows:
namespace namespace_name { // code declarations }
To call the namespace-enabled version of either function or variable, prepend the namespace name as follows:
namespace_name.item_name;
The following program demonstrates use of namespaces:
using System; namespace first_space { class namespace_cl { public void func() { Console.WriteLine("Inside first_space"); } } } namespace second_space { class namespace_cl { public void func() { Console.WriteLine("Inside second_space"); } } } class TestClass { static void Main(string[] args) { first_space.namespace_cl fc = new first_space.namespace_cl(); second_space.namespace_cl sc = new second_space.namespace_cl(); fc.func(); sc.func(); Console.ReadKey(); } }
When the above code is compiled and executed, it produces following result:
Inside first_space Inside second_space
The using Keyword
The using keyword states that the program is using the names in the given namespace. For example, we are using the System namespace in our programs. The class Console is defined there. We just write:
Console.WriteLine ("Hello there");
We could have written the fully qualified name as:
System.Console.WriteLine("Hello there");
You can also avoid prepending of namespaces with the using namespace directive. This directive tells the compiler that the subsequent code is making use of names in the specified namespace. The namespace is thus implied for the following code:
Let us rewrite our preceding example, with using directive:
using System; using first_space; using second_space; namespace first_space { class abc { public void func() { Console.WriteLine("Inside first_space"); } } } namespace second_space { class efg { public void func() { Console.WriteLine("Inside second_space"); } } } class TestClass { static void Main(string[] args) { abc fc = new abc(); efg sc = new efg(); fc.func(); sc.func(); Console.ReadKey(); } }
When the above code is compiled and executed, it produces following result:
Inside first_space Inside second_space
C# - Preprocessor Directives
The preprocessors directives give instruction to the compiler to preprocess the information before actual compilation starts.
All preprocessor directives begin with #, and only white-space characters may appear before a preprocessor directive on a line. Preprocessor directives are not statements, so they do not end with a semicolon (;).
C# compiler does not have a separate preprocessor; however, the directives are processed as if there was one. In C# the preprocessor directives are used to help in conditional compilation. Unlike C and C++ directives, they are not used to create macros. A preprocessor directive must be the only instruction on a line.
List of Preprocessor Directives in C#
The following table lists the preprocessor directives available in C#:
Preprocessor Directive | Description. |
---|---|
#define | It defines a sequence of characters, called symbol. |
#undef | It allows you to undefine a symbol. |
#if | It allows testing a symbol or symbols to see if they evaluate to true. |
#else | It allows to create a compound conditional directive, along with #if. |
#elif | It allows creating a compound conditional directive. |
#endif | specifies the end of a conditional directive. |
#line | It lets you modify the compiler's line number and (optionally) the file name output for errors and warnings. |
#error | It allows generating an error from a specific location in your code. |
#warning | It allows generating a level one warning from a specific location in your code. |
#region | It lets you specify a block of code that you can expand or collapse when using the outlining feature of the Visual Studio Code Editor. |
#endregion | It marks the end of a #region block. |