DATABASE SYSTEMS AND SOFTWARE DEVELOPMENT Page | 1 Table Of Contents UNIT 1........................................................................................................................................ 3 OBJECT-ORIENTED PROGRAMMING. ........................................................................... 3 Introduction to C# ....................................................................................................................... 3 Keywords .................................................................................................................................. 66 Class and Object ..................................................................................................................... 124 Constructors ............................................................................................................................ 129 Inheritance............................................................................................................................... 141 Encapsulation .......................................................................................................................... 148 Abstraction .............................................................................................................................. 151 Methods................................................................................................................................... 155 Method Overloading ............................................................................................................... 165 Method Parameters ................................................................................................................. 172 Method Overriding.................................................................................................................. 182 Anonymous method in C# ...................................................................................................... 199 UNIT 2.................................................................................................................................... 204 UNDERSTANDING DESKTOP APPLICATIONS .......................................................... 204 Human computer interaction .................................................................................................. 204 Windows, forms, applications ................................................................................................. 209 Designing a windows form...................................................................................................... 210 Windows form event model .................................................................................................... 238 Visual inheritance ................................................................................................................... 249 Console-based applications .................................................................................................... 295 Command-line parameters...................................................................................................... 323 Windows services .................................................................................................................... 324 Creating a windows service .................................................................................................... 327 UNIT 3.................................................................................................................................... 334 DATABASE CONCEPTS AND DESIGN .......................................................................... 334 The concept and uses of databases ......................................................................................... 334 COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Relational database concepts ................................................................................................. 347 Relational database design ..................................................................................................... 355 Data normalization ................................................................................................................. 358 Entity-relationship diagrams .................................................................................................. 366 UNIT 4.................................................................................................................................... 373 DATABASE IMPLEMENTATION ................................................................................... 373 Introduction to a DBMS (e.g. MY SQL).................................................................................. 373 Implementing databases.......................................................................................................... 376 Structured query language ...................................................................................................... 376 Advanced database concepts (triggers, stored procedures) .................................................... 396 Database connection methods ................................................................................................ 409 UNIT 5.................................................................................................................................... 415 VERIFICATION AND SYSTEMS TESTING .................................................................. 415 Database testing...................................................................................................................... 415 Unit testing .............................................................................................................................. 425 Integration testing ................................................................................................................... 428 Debugging. .............................................................................................................................. 436 COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 2 UNIT 1 OBJECT-ORIENTED PROGRAMMING. Introduction to C# INTRODUCTION TO C# C# is a general-purpose, modern and object-oriented programming language pronounced as “C sharp”. It was developed by Microsoft led by Anders Hejlsberg and his team within the .Net initiative and was approved by the European Computer Manufacturers Association (ECMA) and International Standards Organization (ISO). C# is among the languages for Common Language Infrastructure and the current version of C# is version 7.2. C# is a lot similar to Java syntactically and is easy for the users who have knowledge of C, C++ or Java. A BIT ABOUT .NET FRAMEWORK .Net applications are multi-platform applications and framework can be used from languages like C++, C#, Visual Basic, COBOL etc. It is designed in a manner so that other languages can use it. know more about .Net Framework WHY C#? C# has many other reasons for being popular and in demand. Few of the reasons are mentioned below: 1. Easy to start: C# is a high-level language so it is closer to other popular programming languages like C, C++, and Java and thus becomes easy to learn for anyone. 2. Widely used for developing Desktop and Web Application: C# is widely used for developing web applications and Desktop applications. It is one of the most popular languages that is used in professional desktop. If anyone wants to create Microsoft apps, C# is their first choice. 3. Community: The larger the community the better it is as new tools and software will be developing to make it better. C# has a large community so the developments are done to make it exist in the system and not become extinct. 4. Game Development: C# is widely used in game development and will continue to dominate. C# integrates with Microsoft and thus has a large target audience. The C# features such as Automatic Garbage Collection, interfaces, object-oriented, etc. make C# a popular game developing language. BEGINNING WITH C# PROGRAMMING: Finding a Compiler: There are various online IDEs such as GeeksforGeeks ide, CodeChef ide etc. which can be used to run C# programs without installing. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 3 Windows: Since the C# is developed within .Net framework initiative by Microsoft, it provide various IDEs to run C# programs: Microsoft Visual Studio, Visual Studio Express, Visual Web Developer Linux: Mono can be used to run C# programs on Linux. Programming in C#: Since the C# is a lot similar to other widely used languages syntactically, it is easier to code and learn in C#. Programs can be written in C# in any of the widely used text editors like Notepad++, gedit, etc. or on any of the compilers. After writing the program save the file with the extension .cs. Example: A simple program to print Hello Geeks // C# program to print Hello Geeks using System; namespace HelloGeeksApp { class HelloGeeks { // Main function static void Main(string[] args) { // Printing Hello Geeks Console.WriteLine("Hello Geeks"); Console.ReadKey(); } } } Output: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 4 Hello Geeks Explanation: 1. Comments: Comments are used for explaining code and are used in similar manner as in Java or C or C++. Compilers ignore the comment entries and does not execute them. Comments can be of single line or multiple lines. Page | 5 Single line Comments: Syntax: // Single line comment Multi line comments: Syntax: /* Multi line comments*/ 2. using System: using keyword is used to include the System namespace in the program. namespace declaration: A namespace is a collection of classes. The HelloGeeksApp namespace contains the class HelloGeeks. 3. class: The class contains the data and methods to be used in the program. Methods define the behavior of the class. Class HelloGeeks has only one method Main similar to JAVA. 4. static void Main(): static keyword tells us that this method is accessible without instantiating the class. 5. void keywords tells that this method will not return anything. Main() method is the entry-point of our application. In our program, Main() method specifies its behavior with the statement Console.WriteLine(“Hello Geeks”); . 6. Console.WriteLine(): WriteLine() is a method of the Console class defined in the System namespace. 7. Console.ReadKey(): This is for the VS.NET Users. This makes the program wait for a key press and prevents the screen from running and closing quickly. Note: C# is case sensitive and all statements and expressions must end with semicolon (;). ADVANTAGES OF C#: • C# is very efficient in managing the system. All the garbage is automatically collected in C#. • There is no problem of memory leak in C# because of its high memory backup. • Cost of maintenance is less and is safer to run as compared to other languages. • C# code is compiled to a intermediate language (Common (.Net) Intermediate Language) which is a standard language, independently irrespective of the target operating system and architecture. DISADVANTAGES OF C#: • C# is less flexible as it depends alot on .Net framework. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) • C# runs slowly and program needs to be compiled each time when any changes are made. APPLICATIONS: • C# is widely used for developing desktop applications, web applications and web services. • It is used in creating applications of Microsoft at a large scale. • C# is also used in game development in Unity. SETTING UP THE ENVIRONMENT IN C# Prerequisite: Introduction to C# C# is a general-purpose, modern and object-oriented programming language pronounced as “C sharp”. It was developed by Microsoft led by Anders Hejlsberg and his team within the .Net initiative and was approved by the European Computer Manufacturers Association (ECMA) and International Standards Organization (ISO). C# is among the languages for Common Language Infrastructure and the current version of C# is version 7.2. C# is a lot similar to Java syntactically and is easy for the users who have knowledge of C, C++ or Java. BASIC COMPONENTS INVOLVED IN PROCESS OF SETTING UP THE ENVIRONMENT IN C# 1. .Net Framework The .NET Framework is a platform for building, deploying, and running Web Services and applications. To run C# applications or any program, it requires installing a .NET Framework component on the system. .NET also supports a lot of programming languages like Visual Basic, Visual C++, etc. And C# is one of the common languages which is included in the .NET Framework. It is consist of two basic components: • Common Language Runtime (CLR): The .NET Framework contains a run-time environment known as CLR which runs the codes. It provides services to make the development process easy. • Framework Class Library (FCL): It is a library of classes, value types, interfaces that provide access to system functionality. In Windows Operating System, .NET Framework is installed by default. To know more about .NET Framework versions, click on .NET Framework Versions. of Microsoft Document. 2. Visual Studio IDE Microsoft has provided an IDE(Integrated Development Environment) tool named Visual Studio to develop applications using different programming languages such as C#, VB(Visual Basic) etc. To install and use Visual Studio for the commercial purpose it must buy a license from Microsoft. For learning (non-commercial) purpose, Microsoft provided a free Visual Studio Community Version. STEPS FOR SETTING UP C# ENVIRONMENT FOR WINDOWS COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 6 Step 1: Download the Visual Studio Community Version Step 2: Run the .exe file and follow the instructions to install Visual Studio Community Version on the system. Step 3: Select .Net Desktop Development from the options and click to install in bottom right corner as shown below : COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 7 Page | 8 Step 4: Open it and it will be prompted to sign in for the first time. The sign-in step is optional so it can be skipped. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 9 Step 5: The dialog box will appear for first time only and ask to choose Development Settings and color theme. Once select required options, click on Start Visual Studio option like as shown below : COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 10 . Step 6: To create a new console application using C#, Go to File –> New –>Project like as shown below Step 7: Choose Console App, write the name of the project and select location path to save project files and then click OK like as shown below. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 11 Step 8: After clicking OK a predefined template will come and start writing C# code. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) HELLO WORLD IN C# • Difficulty Level : Easy • Last Updated : 17 Dec, 2019 The Hello World! program is the most basic and first program when you dive into a new programming language. This simply prints the Hello World! on the output screen. In C#, a basic program consists of the following: • A Namespace Declaration • Class Declaration & Definition • Class Members(like variables, methods etc.) • Main Method • Statements or Expressions Example: // C# program to print Hello World! using System; // namespace declaration namespace HelloWorldApp { // Class declaration class Geeks { // Main Method static void Main(string[] args) { // statement // printing Hello World! Console.WriteLine("Hello World!"); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 12 // To prevents the screen from // running and closing quickly Console.ReadKey(); } } } Output: Hello World! Explanation: • using System: System is a namespace which contains the commonly used types. It is specified with a using System directive. • namespace HelloWorldApp: Here namespace is the keyword which is used to define the namespace. HelloWorldApp is the user-defined name given to namespace. For more details, you can refer to C# | Namespaces • class Geeks: Here class is the keyword which is used for the declaration of classes. Geeks is the user-defined name of the class. • static void Main(string[] args): Here static keyword tells us that this method is accessible without instantiating the class. void keyword tells that this method will not return anything. Main() method is the entry point of our application. In our program, Main() method specifies its behavior with the statement Console.WriteLine(“Hello World!”);. • Console.WriteLine(): Here WriteLine() is a method of the Console class defined in the System namespace. • Console.ReadKey(): This is for the VS.NET Users. This makes the program wait for a key press and prevents the screen from running and closing quickly. HOW TO RUN A C# PROGRAM? Generally, there are 3 ways to compile and execute a C# program as follows: • To use an online C# compiler: You can use various online IDE. which can be used to run C# programs without installing. • Using Visual Studio IDE: Microsoft has provided an IDE(Integrated Development Environment) tool named Visual Studio to develop applications using different programming languages such as C#, VB(Visual Basic) etc. To install and use Visual COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 13 Studio for the commercial purpose it must buy a license from the Microsoft. For learning (non-commercial) purpose, Microsoft provided a free Visual Studio Community Version. To learn how to run a program in Visual Studio you can refer to this. • Using Command-Line: You can also use command-line options to run a C# program. Below steps demonstrate how to run a C# program on Command line in Windows Operating System: • First, open a text editor like Notepad or Notepad++. • Write the code in the text editor and save the file with .cs extension. • Open the cmd(Command Prompt) and run the command csc to check for the compiler version. It specifies whether you have installed a valid compiler or not. You can avoid this step if you confirmed that compiler is installed. • To compile the code type csc filename.cs on cmd. If your program has no error then it will create a filename.exe file in the same directory where you have saved your program. Suppose you saved the above program as hello.cs. So you will write csc hello.cs on cmd. This will create a hello.exe. • Now you have to ways to execute the hello.exe. First, you have to simply type the filename i.e hello on the cmd and it will give the output. Second, you can go to the directory where you saved your program and there you find filename.exe. You have to simply double-click that file and it will give the output. Common Language Runtime (CLR) in C# • Difficulty Level : Medium COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 14 • Last Updated : 23 Aug, 2021 CLR is the basic and Virtual Machine component of the .NET Framework. It is the run-time environment in the .NET Framework that runs the codes and helps in making the development process easier by providing the various services. Basically, it is responsible for managing the execution of .NET programs regardless of any .NET programming language. Internally, CLR Page | 15 implements the VES(Virtual Execution System) which is defined in the Microsoft’s implementation of the CLI(Common Language Infrastructure). The code that runs under the Common Language Runtime is termed as the Managed Code. In other words, you can say that CLR provides a managed execution environment for the .NET programs by improving the security, including the cross language integration and a rich set of class libraries etc. CLR is present in every .NET framework version. Below table illustrate the CLR version in .NET framework. .clr-table { border-collapse: collapse; width: 100%; } .clr-table td { border: 1px solid #5fb962; text-align: center !important; padding: 8px; } .clr-table th { border: 1px solid #5fb962; padding: 8px; } .clr-table tr>th{ background-color: #c6ebd9; vertical-align: middle; } .clr-table tr:nthchild(odd) { background-color: #ffffff; } CLR Versions .NET Framework Versions 1.0 1.0 1.1 1.1 2.0 2.0 2.0 3.0 2.0 3.5 4 4 4 4.5(also 4.5.1 & 4.5.2) COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) CLR Versions .NET Framework Versions 4 4.6(also 4.6.1 & 4.6.2) Page | 16 4 4.7(also 4.7.1 & 4.7.2) Below diagram illustrate how CLR is associated with the operating system/hardware along with the class libraries. Here, the runtime is actually CLR. ROLE OF CLR IN THE EXECUTION OF A C# PROGRAM • Suppose you have written a C# program and save it in a file which is known as the Source Code. • Language specific compiler compiles the source code into the MSIL(Microsoft Intermediate Language) which is also know as the CIL(Common Intermediate Language) or IL(Intermediate Language) along with its metadata. Metadata includes the all the types, actual implementation of each function of the program. MSIL is machine independent code. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) • Now CLR comes into existence. CLR provides the services and runtime environment to the MSIL code. Internally CLR includes the JIT(Just-In-Time) compiler which converts the MSIL code to machine code which further executed by CPU. CLR also uses the .NET Framework class libraries. Metadata provides information about the programming language, environment, version, and class libraries to the CLR by which CLR handles the Page | 17 MSIL code. As CLR is common so it allows an instance of a class that written in a different language to call a method of the class which written in another language. Main Components of CLR As the word specify, Common means CLR provides a common runtime or execution environment as there are more than 60 .NET programming languages. Main components of CLR: COMMON LANGUAGE SPECIFICATION (CLS): It is responsible for converting the different .NET programming language syntactical rules and regulations into CLR understandable format. Basically, it provides the Language Interoperability. Language Interoperability means to provide the execution support to other programming languages also in .NET framework. LANGUAGE INTEROPERABILITY CAN BE ACHIEVED IN TWO WAYS: 1. Managed Code: The MSIL code which is managed by the CLR is known as the Managed Code. For managed code CLR provides three .NET facilities: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) 2. Unmanaged Code: Before .NET development the programming language like .COM Components & Win32 API do not generate the MSIL code. So these are not managed by CLR rather managed by Operating System. Common Type System (CTS): Every programming language has its own data type system, so CTS is responsible for understanding all the data type systems of .NET programming languages and converting them into CLR understandable format which will be a common format. There are 2 Types of CTS that every .NET programming language have : 1. Value Types: Value Types will store the value directly into the memory location. These types work with stack mechanism only. CLR allows memory for these at Compile Time. 2. Reference Types: Reference Types will contain a memory address of value because the reference types won’t store the variable value directly in memory. These types work with Heap mechanism. CLR allots memory for these at Runtime. Garbage Collector: It is used to provide the Automatic Memory Management feature. If there was no garbage collector, programmers would have to write the memory management codes which will be a kind of overhead on programmers. JIT(Just In Time Compiler): It is responsible for converting the CIL(Common Intermediate Language) into machine code or native code using the Common Language Runtime environment. BENEFITS OF CLR: • It improves the performance by providing a rich interact between programs at run time. • Enhance portability by removing the need of recompiling a program on any operating system that supports it. • Security also increases as it analyzes the MSIL instructions whether they are safe or unsafe. Also, the use of delegates in place of function pointers enhance the type safety and security. • Support automatic memory management with the help of Garbage Collector. • Provides cross-language integration because CTS inside CLR provides a common standard that activates the different languages to extend and share each other’s libraries. • Provides support to use the components that developed in other .NET programming languages. • Provide language, platform, and architecture independence. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 18 • It allows easy creation of scalable and multithreaded applications, as the developer has no need to think about the memory management and security issues. C# | IDENTIFIERS In programming languages, identifiers are used for identification purposes. Or in other words, identifiers are the user-defined name of the program components. In C#, an identifier can be a class name, method name, variable name or label. Example: public class GFG { static public void Main () { int x; } } Here the total number of identifiers present in the above example is 3 and the names of these identifiers are: • GFG: Name of the class • Main: Method name • x: Variable name RULES FOR DEFINING IDENTIFIERS IN C#: There are certain valid rules for defining a valid C# identifier. These rules should be followed, otherwise, we will get a compile-time error. • The only allowed characters for identifiers are all alphanumeric characters([A-Z], [az], [0-9]), ‘_‘ (underscore). For example “geek@” is not a valid C# identifier as it contain ‘@’ – special character. • Identifiers should not start with digits([0-9]). For example “123geeks” is a not a valid in C# identifier. • Identifiers should not contain white spaces. • Identifiers are not allowed to use as keyword unless they include @ as a prefix. For example, @as is a valid identifier, but “as” is not because it is a keyword. • C# identifiers allow Unicode Characters. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 19 • C# identifiers are case-sensitive. • C# identifiers cannot contain more than 512 characters. • Identifiers does not contain two consecutive underscores in its name because such types of identifiers are used for the implementation. Example: • CSharp // Simple C# program to illustrate identifiers using System; class GFG { // Main Method static public void Main() { // variable int a = 10; int b = 39; int c; // simple addition c = a + b; Console.WriteLine("The sum of two number is: {0}", c); } } Output: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 20 The sum of two number is: 49 Below table shows the identifiers and keywords present in the above example: Keywords Identifiers using GFG public Main static a void b int c C# | DATA TYPES • Difficulty Level : Basic • Last Updated : 18 Jun, 2020 Data types specify the type of data that a valid C# variable can hold. C# is a strongly typed programming language because in C#, each type of data (such as integer, character, float, and so forth) is predefined as part of the programming language and all constants or variables defined for a given program must be described with one of the data types. Data types in C# is mainly divided into three categories • Value Data Types • Reference Data Types • Pointer Data Type 1. Value Data Types : In C#, the Value Data Types will directly store the variable value in memory and it will also accept both signed and unsigned literals. The derived class for these data types are System.ValueType. Following are different Value Data Types in C# programming language : COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 21 • Alias sbyte short Int byte uint • Signed & Unsigned Integral Types : There are 8 integral types which provide support for 8-bit, 16-bit, 32-bit, and 64-bit values in signed or unsigned form. Type Name System.Sbyte System.Int16 Type signed integer signed integer System.Int32 signed integer System.byte unsigned integer System.UInt32 unsigned integer Size(bits) Range Default Value 8 -128 to 127 0 16 32768 to 32767 0 32 231 to 231-1 8 0 to 255 32 0 to 232 0 0 0 Page | 22 long ushort ulong System.Int64 signed intege System.UInt16 unsign intege System.UInt64 unsign intege Floating Point Types :There are 2 floating point data types which contain the decimal point. • Float: It is 32-bit single-precision floating point type. It has 7 digit Precision. To initialize a float variable, use the suffix f or F. Like, float x = 3.5F;. If the suffix F or f will not use then it is treated as double. • Double:It is 64-bit double-precision floating point type. It has 14 – 15 digit Precision. To initialize a double variable, use the suffix d or D. But it is not mandatory to use suffix because by default floating data types are the double type. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Alias Type name Size(bits) Range (aprox) Default Value float System.Single 32 ±1.5 × 10-45 to ±3.4 × 1038 0.0F Page | 23 double • System.Double 64 ±5.0 × 10-324 to ±1.7 × 10308 0.0D Decimal Types : The decimal type is a 128-bit data type suitable for financial and monetary calculations. It has 28-29 digit Precision. To initialize a decimal variable, use the suffix m or M. Like as, decimal x = 300.5m;. If the suffix m or M will not use then it is treated as double. Alias Type name Size(bits) Range (aprox) Default value decimal System.Decimal 128 ±1.0 × 10-28 to ±7.9228 × 1028 0.0M • Character Types : The character types represents a UTF-16 code unit or represents the 16-bit Unicode character. Alias Type name Size In(Bits) Range Default value char System.Char 16 U +0000 to U +ffff ‘\0’ • Example : // C# program to demonstrate // the above data types using System; namespace ValueTypeTest { class GeeksforGeeks { // Main function static void Main() COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) { // declaring character char a = 'G'; // Integer data type is generally // used for numeric values int i = 89; short s = 56; // this will give error as number // is larger than short range // short s1 = 87878787878; // long uses Integer values which // may signed or unsigned long l = 4564; // UInt data type is generally // used for unsigned integer values uint ui = 95; ushort us = 76; // this will give error as number is // larger than short range COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 24 // ulong data type is generally // used for unsigned integer values ulong ul = 3624573; // by default fraction value // is double in C# double d = 8.358674532; // for float use 'f' as suffix float f = 3.7330645f; // for float use 'm' as suffix decimal dec = 389.5m; Console.WriteLine("char: " + a); Console.WriteLine("integer: " + i); Console.WriteLine("short: " + s); Console.WriteLine("long: " + l); Console.WriteLine("float: " + f); Console.WriteLine("double: " + d); Console.WriteLine("decimal: " + dec); Console.WriteLine("Unsinged integer: " + ui); Console.WriteLine("Unsinged short: " + us); Console.WriteLine("Unsinged long: " + ul); } } } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 25 • Output : • char: G • integer: 89 • short: 56 • long: 4564 • float: 3.733064 • double: 8.358674532 • decimal: 389.5 • Unsinged integer: 95 • Unsinged short: 76 • Unsinged long: 3624573 • Example : // C# program to demonstrate the Sbyte // signed integral data type using System; namespace ValueTypeTest { class GeeksforGeeks { // Main function static void Main() { sbyte a = 126; // sbyte is 8 bit // singned value Console.WriteLine(a); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 26 a++; Console.WriteLine(a); // It overflows here because // byte can hold values // from -128 to 127 a++; Console.WriteLine(a); // Looping back within // the range a++; Console.WriteLine(a); } } } • Output : • 126 • 127 • -128 • -127 • Example : • • // C# program to demonstrate COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 27 // the byte data type using System; namespace ValueTypeTest { class GeeksforGeeks { // Main function static void Main() { byte a = 0; // byte is 8 bit // unsigned value Console.WriteLine(a); a++; Console.WriteLine(a); a = 254; // It overflows here because // byte can hold values from // 0 to 255 a++; Console.WriteLine(a); // Looping back within the range COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 28 a++; Console.WriteLine(a); } Page | 29 } } • Output : • 0 • 1 • 255 • 0 • Boolean Types : It has to be assigned either true or false value. Values of type bool are not converted implicitly or explicitly (with casts) to any other type. But the programmer can easily write conversion code. Alias Type name Values bool System.Boolean True / False • Example : // C# program to demonstrate the // boolean data type using System; namespace ValueTypeTest { class GeeksforGeeks { // Main function static void Main() COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) { // boolean data type bool b = true; if (b == true) Console.WriteLine("Hi Geek"); } } } • Output : • Hi Geek 2. Reference Data Types : The Reference Data Types will contain a memory address of variable value because the reference types won’t store the variable value directly in memory. The built-in reference types are string, object. • String : It represents a sequence of Unicode characters and its type name is System.String. So, string and String are equivalent. Example : • string s1 = "hello"; // creating through string keyword • String s2 = "welcome"; // creating through String class • Object : In C#, all types, predefined and user-defined, reference types and value types, inherit directly or indirectly from Object. So basically it is the base class for all the data types in C#. Before assigning values, it needs type conversion. When a variable of a value type is converted to object, it’s called boxing. When a variable of type object is converted to a value type, it’s called unboxing. Its type name is System.Object. Example : // C# program to demonstrate // the Reference data types using System; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 30 namespace ValueTypeTest { class GeeksforGeeks { // Main Function static void Main() { // declaring string string a = "Geeks"; //append in a a+="for"; a = a+"Geeks"; Console.WriteLine(a); // declare object obj object obj; obj = 20; Console.WriteLine(obj); // to show type of object // using GetType() Console.WriteLine(obj.GetType()); } } } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 31 Output : GeeksforGeeks 20 System.Int32 3. Pointer Data Type : The Pointer Data Types will contain a memory address of the variable value. To get the pointer details we have a two symbols ampersand (&) and asterisk (*). ampersand (&): It is Known as Address Operator. It is used to determine the address of a variable. asterisk (*): It also known as Indirection Operator. It is used to access the value of an address. Syntax : 4. type* identifier; Example : int* p1, p; // Valid syntax int *p1, *p; // Invalid Example : // Note: This program will not work on // online compiler // Error: Unsafe code requires the `unsafe' // command line option to be specified // For its solution: // Go to your project properties page and // check under Build the checkbox Allow // unsafe code. using System; namespace Pointerprogram { class GFG { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 32 // Main function static void Main() { unsafe { // declare variable int n = 10; // store variable n address // location in pointer variable p int* p = &n; Console.WriteLine("Value :{0}", n); Console.WriteLine("Address :{0}", (int)p); } } } } C# | VARIABLES A typical program uses various values that may change during its execution. For example, a program that performs some operations on the values entered by the user. The values entered by one user may differ from those entered by another user. Hence this makes it necessary to use variables as another user may not use the same values. When a user enters a new value that will be used in the process of operation, can store temporarily in the Random Access Memory of computer and these values in this part of memory vary throughout the execution and hence another term for this came which is known as Variables. So basically, a Variable is a placeholder of the information which can be changed at runtime. And variables allows to Retrieve and Manipulate the stored information. Syntax: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 33 type variable_name = value; or type variable_names; Example: char var = 'h'; // Declaring and Initializing character variable int a, b, c; // Declaring variables a, b and c of int type CHARACTERISTICS OF VARIABLES: • name : It must be a valid identifier. In above example, var is a valid identifier. • type : It defines the types of information which is to be stored into the variable. In above example char is a type. • value : It is the actual data which is to be stored in the variable. In above example ‘h’ is the value. RULES FOR NAMING VARIABLES • Variable names can contain the letters ‘a-z’ or ’A-Z’ or digits 0-9 as well as the character ‘_’. • The name of the variables cannot be started with a digit. • The name of the variable cannot be any C# keyword say int, float, null, String, etc. Examples: • Valid Variables Names • int age; • float _studentname; • Invalid Variables Names • int if; // "if" is a keyword • • float 12studentname; // Cannot start with digit Defining or Declaring a Variable There are some rules that must be followed while declaring variables : • specify its type (such as int) COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 34 • specify its name (such as age) • Can provide initial value(such as 17) Example : int geeks; float interest; INITIALIZING VARIABLES The term initializing means to assign some value to the variable. Basically, the actual use of variables comes under the initialization part. In C# each data type has some default value which is used when there is no explicitly set value for a given variable. Initialization can be done separately or may be with declaration. Example : int y = 7; // Declaring and initializing the variable at same time int x; // Declaring variable x x = 5; // initializing x with value 5 TWO WAYS FOR INITIALIZATION: 1. Compile time initialization 2. Run time initialization 1. Compile Time Initialization It means to provide the value to the variable during the compilation of the program. If the programmer didn’t provide any value then the compiler will provide some default value to the variables in some cases. Generally, this type of initialization helpful when the programmer wants to provide some default value. Example : // C# program to demonstrate the // Compile Time Initialization using System; class Geeks { // only declaration, compiler will COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 35 // provide the default value 0 to it int y; // Main Method public static void Main(String []args) { // Compile Time Initialization of variable 'x' // Assigning value 32 to x int x = 32; // printing the value Console.WriteLine("Value of x is "+x); // creating object to access // the variable y Geeks gfg = new Geeks(); // printing the value Console.WriteLine("Value of y is "+gfg.y); } } Output : Value of x is 32 Value of y is 0 2. Run Time Initialization COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 36 In this, the user has to enter the value and that value is copied to the required variable. In this type of initialization, there is one more possibility in which value is assigned to variable after completion of a function call. Example: Input : 45 Output : Value of num is 45 Input : 27 Output : Value of num is 27 // C# program to demonstrate the // Run Time Initialization using System; class Geeks { // Main Method public static void Main(String []args) { // Value will be taken from user // input and assigned to variable // num int num = Convert.ToInt32(Console.ReadLine()); // printing the result Console.WriteLine("Value of num is " + num); } } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 37 Output : Value of num is 45 Note: Here the Console.ReadLine() method asks the user to enter the value and later on it puts the same value in the “num” variable. Hence the value will be displayed according to the user input. C# | LITERALS • Difficulty Level : Basic • Last Updated : 05 Nov, 2020 The fixed values are called as Literal. Literal is a value that is used by the variables. Values can be either an integer, float or string, etc. // Here 100 is a constant/literal. int x = 100; Literals can be of the following types: • Integer Literals • Floating-point Literals • Character Literals • String Literals • Null Literals • Boolean Literals Integer Literals: A literal of integer type is know as the integer literal. It can be octal, decimal, binary, or hexadecimal constant. No prefix is required for the decimal numbers. A suffix can also be used with the integer literals like U or u are used for unsigned numbers while l or L are used for long numbers. By default, every literal is of int type. For Integral data types (byte, short, int, long), we can specify literals in the ways: • Decimal literals (Base 10): In this form, the allowed digits are 0-9. int x = 101; • Octal literals (Base 8): In this form, the allowed digits are 0-7. // The octal number should be prefix with 0. int x = 0146; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 38 • Hexa-decimal literals (Base 16): In this form, the allowed digits are 0-9 and characters are a-f. We can use both uppercase and lowercase characters. As we know that c# is a case-sensitive programming language but here c# is not case-sensitive. // The hexa-decimal number should be prefix // with 0X or 0x. int x = 0X123Face; • Binary literals (Base 2): In this form, the allowed digits are only 1’s and 0’s. // The binary number should be prefix with 0b. int x = 0b101 Examples: 07778 // invalid: 8 is not an octal digit 045uu // invalid: suffix (u) is repeated 0b105 // invalid: 5 is not a binary digit 0b101 // valid binary literal 456 // valid decimal literal 02453 // valid octal literal 0x65d // valid hexadecimal literal 12356 // valid int literal 304U // valid unsigned int literal 3078L // valid long literal 965UL // valid unsigned long literal PROGRAM: • C# // C# program to illustrate the use of Integer Literals using System; class Geeks{ COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 39 // Main method public static void Main(String[] args) { Page | 40 // decimal-form literal int a = 101; // octal-form literal int b = 0145; // Hexa-decimal form literal int c = 0xFace; // binary-form literal int x = 0b101; Console.WriteLine(a); Console.WriteLine(b); Console.WriteLine(c); Console.WriteLine(x); } } 101 145 64206 5 COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Floating-point Literals: The literal which has an integer part, a decimal point, a fractional part, and an exponent part is known as the floating-point literal. These can be represented either in decimal form or exponential form. Examples: Double d = 3.14145 // Valid Double d = 312569E-5 // Valid Double d = 125E Double d = 784f Double d = .e45 // invalid: Incomplete exponent // valid // invalid: missing integer or fraction Program: • C# // C# program to illustrate the use of // floating-point literals using System; class Geeks { // Main Method public static void Main(String[] args) { // decimal-form literal double a = 101.230; // It also acts as decimal literal double b = 0123.222; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 41 Console.WriteLine(a); Console.WriteLine(b); } } Output: 101.23 123.222 Note: By default, every floating-point literal is of double type and hence we can’t assign directly to float variable. But we can specify floating-point literal as float type by suffixed with f or F. We can specify explicitly floating-point literal as the double type by suffixed with d or D, of course, this convention is not required. Character Literals: For character data types we can specify literals in 3 ways: • Single quote: We can specify literal to char data type as single character within single quote. char ch = 'a'; • Unicode Representation: We can specify char literals in Unicode representation ‘\uxxxx’. Here xxxx represents 4 hexadecimal numbers. char ch = '\u0061';// Here /u0061 represent a. • Escape Sequence: Every escape character can be specified as char literals. char ch = '\n'; Escape Sequence Meaning \\ \ character \’ ‘ character COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 42 Escape Sequence Meaning \? ? character Page | 43 \” ” character \b Backspace \a Alert or Bell \n New Line \f Form Feed \r Carriage Return \v Vertical Tab \xhh… Hexadecimal number of one or more digits Example : • C# // C# program to illustrate the use of char literals using System; class Geeks { // Main Method COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) public static void Main(String[] args) { // character literal within single quote char ch = 'a'; // Unicode representation char c = '\u0061'; Console.WriteLine(ch); Console.WriteLine(c); // Escape character literal Console.WriteLine("Hello\n\nGeeks\t!"); } } a a Hello Geeks ! String Literals: Literals which are enclosed in double quotes(“”) or starts with @”” are known as the String literals. Examples: String s1 = "Hello Geeks!"; String s2 = @"Hello Geeks!"; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 44 Program: • C# // C# program to illustrate the use of String literals using System; class Geeks { // Main Method public static void Main(String[] args) { String s = "Hello Geeks!"; String s2 = @"Hello Geeks!"; // If we assign without "" then it // treats as a variable // and causes compiler error // String s1 = Geeks; Console.WriteLine(s); Console.WriteLine(s2); } } Output: Hello Geeks! Hello Geeks! COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 45 Boolean Literals: Only two values are allowed for Boolean literals i.e. true and false. Example: bool b = true; bool c = false; Program: • C# // C# program to illustrate the use // of boolean literals using System; class Geeks { // Main Method public static void Main(String[] args) { bool b = true; bool c = false; // these will give compile time error // bool d = 0; // bool e = 1; // Console.WriteLine(d); // Console.WriteLine(e); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 46 Console.WriteLine(b); Console.WriteLine(c); } } Output: True False C# | OPERATORS Operators are the foundation of any programming language. Thus the functionality of C# language is incomplete without the use of operators. Operators allow us to perform different kinds of operations on operands. In C#, operators Can be categorized based upon their different functionality : • Arithmetic Operators • Relational Operators • Logical Operators • Bitwise Operators • Assignment Operators • Conditional Operator In C#, Operators can also categorized based upon Number of Operands : • Unary Operator: Operator that takes one operand to perform the operation. • Binary Operator: Operator that takes two operands to perform the operation. • Ternary Operator: Operator that takes three operands to perform the operation. ARITHMETIC OPERATORS These are used to perform arithmetic/mathematical operations on operands. The Binary Operators falling in this category are : • Addition: The ‘+’ operator adds two operands. For example, x+y. • Subtraction: The ‘-‘ operator subtracts two operands. For example, x-y. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 47 • Multiplication: The ‘*’ operator multiplies two operands. For example, x*y. • Division: The ‘/’ operator divides the first operand by the second. For example, x/y. • Modulus: The ‘%’ operator returns the remainder when first operand is divided by the second. For example, x%y. Example: • C# // C# program to demonstrate the working // of Binary Arithmetic Operators using System; namespace Arithmetic { class GFG { // Main Function static void Main(string[] args) { int result; int x = 10, y = 5; // Addition result = (x + y); Console.WriteLine("Addition Operator: " + result); // Subtraction result = (x - y); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 48 Console.WriteLine("Subtraction Operator: " + result); // Multiplication result = (x * y); Console.WriteLine("Multiplication Operator: "+ result); // Division result = (x / y); Console.WriteLine("Division Operator: " + result); // Modulo result = (x % y); Console.WriteLine("Modulo Operator: " + result); } } } Output: Addition Operator: 15 Subtraction Operator: 5 Multiplication Operator: 50 Division Operator: 2 Modulo Operator: 0 The ones falling into the category of Unary Operators are: • Increment: The ‘++’ operator is used to increment the value of an integer. When placed before the variable name (also called pre-increment operator), its value is incremented instantly. For example, ++x. And when it is placed after the variable name (also called post-increment operator), its value is preserved temporarily until the execution of this statement and it gets updated before the execution of the next statement. For example, x++. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 49 • Decrement: The ‘–‘ operator is used to decrement the value of an integer. When placed before the variable name (also called pre-decrement operator), its value is decremented instantly. For example, –x. And when it is placed after the variable name (also called post-decrement operator), its value is preserved temporarily until the execution of this statement and it gets updated Page | 50 before the execution of the next statement. For example, x–. Example: • C# // C# program to demonstrate the working // of Unary Arithmetic Operators using System; namespace Arithmetic { class GFG { // Main Function static void Main(string[] args) { int a = 10, res; // post-increment example: // res is assigned 10 only, // a is not updated yet res = a++; //a becomes 11 now Console.WriteLine("a is {0} and res is {1}", a, res); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) // post-decrement example: // res is assigned 11 only, a is not updated yet res = a--; //a becomes 10 now Console.WriteLine("a is {0} and res is {1}", a, res); // pre-increment example: // res is assigned 11 now since a // is updated here itself res = ++a; // a and res have same values = 11 Console.WriteLine("a is {0} and res is {1}", a, res); // pre-decrement example: // res is assigned 10 only since // a is updated here itself res = --a; // a and res have same values = 10 Console.WriteLine("a is {0} and res is {1}",a, res); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 51 } } } Page | 52 Output: a is 11 and res is 10 a is 10 and res is 11 a is 11 and res is 11 a is 10 and res is 10 Relational Operators Relational operators are used for comparison of two values. Let’s see them one by one: • ‘=='(Equal To) operator checks whether the two given operands are equal or not. If so, it returns true. Otherwise it returns false. For example, 5==5 will return true. • ‘!='(Not Equal To) operator checks whether the two given operands are equal or not. If not, it returns true. Otherwise it returns false. It is the exact boolean complement of the ‘==’ operator. For example, 5!=5 will return false. • ‘>'(Greater Than) operator checks whether the first operand is greater than the second operand. If so, it returns true. Otherwise it returns false. For example, 6>5 will return true. • ‘<‘(Less Than) operator checks whether the first operand is lesser than the second operand. If so, it returns true. Otherwise it returns false. For example, 6<5 will return false. • ‘>='(Greater Than Equal To) operator checks whether the first operand is greater than or equal to the second operand. If so, it returns true. Otherwise it returns false. For example, 5>=5 will return true. • ‘<='(Less Than Equal To) operator checks whether the first operand is lesser than or equal to the second operand. If so, it returns true. Otherwise it returns false. For example, 5<=5 will also return true. Example: • C# // C# program to demonstrate the working COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) // of Relational Operators using System; namespace Relational { class GFG { // Main Function static void Main(string[] args) { bool result; int x = 5, y = 10; // Equal to Operator result = (x == y); Console.WriteLine("Equal to Operator: " + result); // Greater than Operator result = (x > y); Console.WriteLine("Greater than Operator: " + result); // Less than Operator result = (x < y); Console.WriteLine("Less than Operator: " + result); // Greater than Equal to Operator result = (x >= y); Console.WriteLine("Greater than or Equal to: "+ result); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 53 // Less than Equal to Operator result = (x <= y); Console.WriteLine("Lesser than or Equal to: "+ result); // Not Equal To Operator result = (x != y); Console.WriteLine("Not Equal to Operator: " + result); } } } Output: Equal to Operator: False Greater than Operator: False Less than Operator: True Greater than or Equal to: False Lesser than or Equal to: True Not Equal to Operator: True Logical Operators They are used to combine two or more conditions/constraints or to complement the evaluation of the original condition in consideration. They are described below: • Logical AND: The ‘&&’ operator returns true when both the conditions in consideration are satisfied. Otherwise it returns false. For example, a && b returns true when both a and b are true (i.e. non-zero). • Logical OR: The ‘||’ operator returns true when one (or both) of the conditions in consideration is satisfied. Otherwise it returns false. For example, a || b returns true if one of a or b is true (i.e. non-zero). Of course, it returns true when both a and b are true. • Logical NOT: The ‘!’ operator returns true the condition in consideration is not satisfied. Otherwise it returns false. For example, !a returns true if a is false, i.e. when a=0. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 54 Example: • C# // C# program to demonstrate the working // of Logical Operators using System; namespace Logical { class GFG { // Main Function static void Main(string[] args) { bool a = true,b = false, result; // AND operator result = a && b; Console.WriteLine("AND Operator: " + result); // OR operator result = a || b; Console.WriteLine("OR Operator: " + result); // NOT operator result = !a; Console.WriteLine("NOT Operator: " + result); } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 55 } } Output: AND Operator: False OR Operator: True NOT Operator: False Bitwise Operators In C#, there are 6 bitwise operators which work at bit level or used to perform bit by bit operations. Following are the bitwise operators : • & (bitwise AND) Takes two numbers as operands and does AND on every bit of two numbers. The result of AND is 1 only if both bits are 1. • | (bitwise OR) Takes two numbers as operands and does OR on every bit of two numbers. The result of OR is 1 any of the two bits is 1. • ^ (bitwise XOR) Takes two numbers as operands and does XOR on every bit of two numbers. The result of XOR is 1 if the two bits are different. • << (left shift) Takes two numbers, left shifts the bits of the first operand, the second operand decides the number of places to shift. • >> (right shift) Takes two numbers, right shifts the bits of the first operand, the second operand decides the number of places to shift. Example: • C# // C# program to demonstrate the working // of Bitwise Operators using System; namespace Bitwise { class GFG { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 56 // Main Function static void Main(string[] args) { int x = 5, y = 10, result; // Bitwise AND Operator result = x & y; Console.WriteLine("Bitwise AND: " + result); // Bitwise OR Operator result = x | y; Console.WriteLine("Bitwise OR: " + result); // Bitwise XOR Operator result = x ^ y; Console.WriteLine("Bitwise XOR: " + result); // Bitwise AND Operator result = ~x; Console.WriteLine("Bitwise Complement: " + result); // Bitwise LEFT SHIFT Operator result = x << 2; Console.WriteLine("Bitwise Left Shift: " + result); // Bitwise RIGHT SHIFT Operator result = x >> 2; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 57 Console.WriteLine("Bitwise Right Shift: " + result); } Page | 58 } } Output: Bitwise AND: 0 Bitwise OR: 15 Bitwise XOR: 15 Bitwise Complement: -6 Bitwise Left Shift: 20 Bitwise Right Shift: 1 Assignment Operators Assignment operators are used to assigning a value to a variable. The left side operand of the assignment operator is a variable and right side operand of the assignment operator is a value. The value on the right side must be of the same data-type of the variable on the left side otherwise the compiler will raise an error. DIFFERENT TYPES OF ASSIGNMENT OPERATORS ARE SHOWN BELOW: • “=”(Simple Assignment): This is the simplest assignment operator. This operator is used to assign the value on the right to the variable on the left. Example: a = 10; b = 20; ch = 'y'; • “+=”(Add Assignment): This operator is combination of ‘+’ and ‘=’ operators. This operator first adds the current value of the variable on left to the value on the right and then assigns the result to the variable on the left. Example: (a += b) can be written as (a = a + b) If initially value stored in a is 5. Then (a += 6) = 11. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) • “-=”(Subtract Assignment): This operator is combination of ‘-‘ and ‘=’ operators. This operator first subtracts the current value of the variable on left from the value on the right and then assigns the result to the variable on the left. Example: (a -= b) can be written as (a = a - b) If initially value stored in a is 8. Then (a -= 6) = 2. • “*=”(Multiply Assignment): This operator is combination of ‘*’ and ‘=’ operators. This operator first multiplies the current value of the variable on left to the value on the right and then assigns the result to the variable on the left. Example: (a *= b) can be written as (a = a * b) If initially value stored in a is 5. Then (a *= 6) = 30. • “/=”(Division Assignment): This operator is combination of ‘/’ and ‘=’ operators. This operator first divides the current value of the variable on left by the value on the right and then assigns the result to the variable on the left. Example: (a /= b) can be written as (a = a / b) If initially value stored in a is 6. Then (a /= 2) = 3. • “%=”(Modulus Assignment): This operator is combination of ‘%’ and ‘=’ operators. This operator first modulo the current value of the variable on left by the value on the right and then assigns the result to the variable on the left. Example: (a %= b) can be written as (a = a % b) If initially value stored in a is 6. Then (a %= 2) = 0. • “<<=”(Left Shift Assignment) : This operator is combination of ‘<<‘ and ‘=’ operators. This operator first Left shift the current value of the variable on left by the value on the right and then assigns the result to the variable on the left. Example: (a <<= 2) can be written as (a = a << 2) If initially value stored in a is 6. Then (a <<= 2) = 24. • “>>=”(Right Shift Assignment) : This operator is combination of ‘>>’ and ‘=’ operators. This operator first Right shift the current value of the variable on left by the value on the right and then assigns the result to the variable on the left. Example: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 59 (a >>= 2) can be written as (a = a >> 2) If initially value stored in a is 6. Then (a >>= 2) = 1. • “&=”(Bitwise AND Assignment): This operator is combination of ‘&’ and ‘=’ operators. This operator first “Bitwise AND” the current value of the variable on the left by the value on the right and then assigns the result to the variable on the left. Example: (a &= 2) can be written as (a = a & 2) If initially value stored in a is 6. Then (a &= 2) = 2. • “^=”(Bitwise Exclusive OR): This operator is combination of ‘^’ and ‘=’ operators. This operator first “Bitwise Exclusive OR” the current value of the variable on left by the value on the right and then assigns the result to the variable on the left. Example: (a ^= 2) can be written as (a = a ^ 2) If initially value stored in a is 6. Then (a ^= 2) = 4. • “|=”(Bitwise Inclusive OR) : This operator is combination of ‘|’ and ‘=’ operators. This operator first “Bitwise Inclusive OR” the current value of the variable on left by the value on the right and then assigns the result to the variable on the left. Example : (a |= 2) can be written as (a = a | 2) If initially, value stored in a is 6. Then (a |= 2) = 6. Example: • C# // C# program to demonstrate the working // of Assignment Operators using System; namespace Assignment { class GFG { // Main Function COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 60 static void Main(string[] args) { // initialize variable x // using Simple Assignment // Operator "=" int x = 15; // it means x = x + 10 x += 10; Console.WriteLine("Add Assignment Operator: " + x); // initialize variable x again x = 20; // it means x = x - 5 x -= 5; Console.WriteLine("Subtract Assignment Operator: " + x); // initialize variable x again x = 15; // it means x = x * 5 x *= 5; Console.WriteLine("Multiply Assignment Operator: " + x); // initialize variable x again COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 61 x = 25; // it means x = x / 5 x /= 5; Console.WriteLine("Division Assignment Operator: " + x); // initialize variable x again x = 25; // it means x = x % 5 x %= 5; Console.WriteLine("Modulo Assignment Operator: " + x); // initialize variable x again x = 8; // it means x = x << 2 x <<= 2; Console.WriteLine("Left Shift Assignment Operator: " + x); // initialize variable x again x = 8; // it means x = x >> 2 x >>= 2; x); Console.WriteLine("Right Shift Assignment Operator: " + COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 62 // initialize variable x again x = 12; // it means x = x >> 4 x &= 4; + x); Console.WriteLine("Bitwise AND Assignment Operator: " // initialize variable x again x = 12; // it means x = x >> 4 x ^= 4; Console.WriteLine("Bitwise Exclusive OR Assignment Operator: " + x); // initialize variable x again x = 12; // it means x = x >> 4 x |= 4; Console.WriteLine("Bitwise Inclusive OR Assignment Operator: " + x); } } } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 63 Output : Add Assignment Operator: 25 Subtract Assignment Operator: 15 Multiply Assignment Operator: 75 Division Assignment Operator: 5 Modulo Assignment Operator: 0 Left Shift Assignment Operator: 32 Right Shift Assignment Operator: 2 Bitwise AND Assignment Operator: 4 Bitwise Exclusive OR Assignment Operator: 8 Bitwise Inclusive OR Assignment Operator: 12 Conditional Operator It is ternary operator which is a shorthand version of if-else statement. It has three operands and hence the name ternary. It will return one of two values depending on the value of a Boolean expression. Syntax: condition ? first_expression : second_expression; Explanation: condition: It must be evaluated to true or false. If the condition is true first_expression is evaluated and becomes the result. If the condition is false, second_expression is evaluated and becomes the result. Example: • C# // C# program to demonstrate the working // of Conditional Operator using System; namespace Conditional { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 64 class GFG { // Main Function static void Main(string[] args) { int x = 5, y = 10, result; // To find which value is greater // Using Conditional Operator result = x > y ? x : y; // To display the result Console.WriteLine("Result: " + result); // To find which value is greater // Using Conditional Operator result = x < y ? x : y; // To display the result Console.WriteLine("Result: " + result); } } } Output : Result: 10 Result: 5 COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 65 Keywords C# | KEYWORDS • Last Updated : 21 Jan, 2019 Keywords or Reserved words are the words in a language that are used for some internal process or represent some predefined actions. These words are therefore not allowed to use as variable names or objects. Doing this will result in a compile-time error. Example: // C# Program to illustrate the keywords using System; class GFG { // Here static, public, void // are keywords static public void Main () { // here int is keyword // a is identifier int a = 10; Console.WriteLine("The value of a is: {0}",a); // this is not a valid identifier // removing comment will give compile time error // double int = 10; } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 66 } Output: The value of a is: 10 There are total 78 keywords in C# as follows: abstract as base bool break byte case catch char checked class const COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 67 continue decimal default delegate do double else enum event explicit extern false finally fixed COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 68 float for foreach goto if implicit in int interface internal is lock long namespace COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 69 new null object operator out override params private protected public readonly ref return sbyte COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 70 sealed short sizeof stackalloc static string struct switch this throw true try typeof unit COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 71 ulong unchecked unsafe ushort using using static virtual void volatile while KEYWORDS IN C# IS MAINLY DIVIDED INTO 10 CATEGORIES AS FOLLOWS: 1. Value Type Keywords: There are 15 keywords in value types which are used to define various data types. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 72 bool byte char decimal double enum float int long sbyte short struct unit ulong ushort 2. Example: 3. 4. // C# Program to illustrate the // value type keywords using System; class GFG { // Here static, public, void // are keywords static public void Main () { // here byte is keyword // a is identifier byte a = 47; Console.WriteLine("The value of a is: {0}",a); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 73 // here bool is keyword // b is identifier // true is a keyword Page | 74 bool b = true; Console.WriteLine("The value of b is: {0}",b); } } 5. Output: 6. The value of a is: 47 7. The value of b is: True 8. Reference Type Keywords: There are 6 keywords in reference types which are used to store references of the data or objects. The keywords in this category are: class, delegate, interface, object, string, void. 9. Modifiers Keywords: There are 17 keywords in modifiers which are used to modify the declarations of type member. public private internal protected abstract const event extern new override partial readonly sealed static unsafe virtual volatile 10. Example: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) // C# Program to illustrate the // modifiers keywords using System; class Geeks { class Mod { // using public modifier // keyword public int n1; } // Main Method static void Main(string[] args) { Mod obj1 = new Mod(); // access to public members obj1.n1 = 77; Console.WriteLine("Value of n1: {0}", obj1.n1); } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 75 } 11. Output: 12. Value of n1: 77 Page | 76 13. Statements Keywords: There are total 18 keywords which are used in program instructions. if else switch do for foreach in while break continue goto return throw try catch finally checked unchecked 14. Example: // C# program to illustrate the statement keywords using System; class demoContinue { public static void Main() { // using for as statement keyword // GeeksforGeeks is printed only 2 times // because of continue statement for(int i = 1; i < 3; i++) { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) // here if and continue are keywords if(i == 2) continue; Console.WriteLine("GeeksforGeeks"); } } } 15. Output: 16. GeeksforGeeks 17. Method Parameters Keywords: There are total 4 keywords which are used to change the behavior of the parameters that passed to a method. The keyword includes in this category are: params, in, ref, out. 18. Namespace Keywords: There are total 3 keywords in this category which are used in namespaces. The keywords are: namespace, using, extern. 19. Operator Keywords: There are total 8 keywords which are used for different purposes like creating objects, getting a size of object etc. The keywords are: as, is, new, sizeof, typeof, true, false, stackalloc. 20. Conversion Keywords: There are 3 keywords which are used in type conversions. The keywords are: explicit, implicit, operator. 21. Access Keywords: There are 2 keywords which are used in accessing and referencing the class or instance of the class. The keywords are base, this. 22. Literal Keywords: There are 2 keywords which are used as literal or constant. The keywords are null, default. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 77 IMPORTANT POINTS: • Keywords are not used as an identifier or name of a class, variable, etc. • If you want to use a keyword as an identifier then you must use @ as a prefix. For example, @abstract is valid identifier but not abstract because it is a keyword. Example: int a = 10; // Here int is a valid keyword double int = 10.67; // invalid because int is a keyword double @int = 10.67; // valid identifier, prefixed with @ int @null = 0; // valid // C# Program to illustrate the use of // prefixing @ in keywords using System; class GFG { // Here static, public, void // are keywords static public void Main () { // here int is keyword // a is identifier int a = 10; Console.WriteLine("The value of a is: {0}",a); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 78 // prefix @ in keyword int which // makes it a valid identifier int @int = 11; Console.WriteLine("The value of a is: {0}",@int); } } Output: The value of a is: 10 The value of a is: 11 Contextual Keywords These are used to give a specific meaning in the program. Whenever a new keyword comes in C#, it is added to the contextual keywords, not in the keyword category. This helps to avoid the crashing of programs which are written in earlier versions. Important Points: • These are not reserved words. • It can be used as identifiers outside the context that’s why it named contextual keywords. • These can have different meanings in two or more contexts. • There are total 30 contextual keywords in C#. add alias ascending COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 79 async await by descending dynamic equals from get global group into join let nameof COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 80 on orderby partial(type) partial(method) remove select set value var when where where yield COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 81 Example: // C# program to illustrate contextual keywords using System; public class Student { // Declare name field private string name = "GeeksforGeeks"; // Declare name property public string Name { // get is contextual keyword get { return name; } // set is a contextual // keyword set { name = value; } } } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 82 class TestStudent { // Main Method public static void Main(string[] args) { Student s = new Student(); // calls set accessor of the property Name, // and pass "GFG" as value of the // standard field 'value'. s.Name = "GFG"; // displays GFG, Calls the get accessor // of the property Name. Console.WriteLine("Name: " + s.Name); // using get and set as identifier int get = 50; int set = 70; Console.WriteLine("Value of get is: {0}",get); Console.WriteLine("Value of set is: {0}",set); } } Output: Name: GFG COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 83 Value of get is: 50 Value of set is: 70 Reference: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/ C# DECISION MAKING (IF, IF-ELSE, IF-ELSE-IF LADDER, NESTED IF, SWITCH, NESTED SWITCH) Decision Making in programming is similar to decision making in real life. In programming too, a certain block of code needs to be executed when some condition is fulfilled. A programming language uses control statements to control the flow of execution of program based on certain conditions. These are used to cause the flow of execution to advance and branch based on changes to the state of a program. The conditional statements of C#: • if • if-else • if-else-if • Nested if • Switch • Nested switch IF Statement The if statement checks the given condition. If the condition evaluates to be true then the block of code/statements will execute otherwise not. Syntax: if(condition) { //code to be executed } Note: If the curly brackets { } are not used with if statements than the statement just next to it is only considered associated with the if statement. Example: if (condition) statement 1; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 84 statement 2; In this example, only statement 1 is considered to be associated with the if statement. Flowchart: Page | 85 Example: • Csharp // C# program to illustrate if statement using System; public class GFG { public static void Main(string[] args) { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) string name = "Geek"; if (name == "Geek") { Console.WriteLine("GeeksForGeeks"); } } } Output: GeeksForGeeks IF – else Statement The if statement evaluates the code if the condition is true but what if the condition is not true, here comes the else statement. It tells the code what to do when the if condition is false. Syntax: if(condition) { // code if condition is true } else { // code if condition is false } Flowchart: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 86 Page | 87 Example: • Csharp // C# program to illustrate // if-else statement using System; public class GFG { public static void Main(string[] args) { string name = "Geek"; if (name == "Geeks") { Console.WriteLine("GeeksForGeeksr"); } else { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Console.WriteLine("Geeks"); } } Page | 88 } Output: Geeks If – else – if ladder Statement The if-else-if ladder statement executes one condition from multiple statements. The execution starts from top and checked for each if condition. The statement of if block will be executed which evaluates to be true. If none of the if condition evaluates to be true then the last else block is evaluated. Syntax: if(condition1) { // code to be executed if condition1 is true } else if(condition2) { // code to be executed if condition2 is true } else if(condition3) { // code to be executed if condition3 is true } ... COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) else { // code to be executed if all the conditions are false } Page | 89 Flowchart: Example: • Csharp COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) // C# program to illustrate // if-else-if ladder using System; class GFG { public static void Main(String[] args) { int i = 20; if (i == 10) Console.WriteLine("i is 10"); else if (i == 15) Console.WriteLine("i is 15"); else if (i == 20) Console.WriteLine("i is 20"); else Console.WriteLine("i is not present"); } } Output: i is 20 Nested – If Statement if statement inside an if statement is known as nested if. if statement in this case is the target of another if or else statement. When more then one condition needs to be true and one of the condition is the sub-condition of parent condition, nested if can be used. Syntax: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 90 if (condition1) { // code to be executed // if condition2 is true if (condition2) { // code to be executed // if condition2 is true } } Flowchart: Example: • csharp COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 91 // C# program to illustrate // nested-if statement using System; class GFG { public static void Main(String[] args) { int i = 10; if (i == 10) { // Nested - if statement // Will only be executed if statement // above it is true if (i < 12) Console.WriteLine("i is smaller than 12 too"); else Console.WriteLine("i is greater than 15"); } } } Output: i is smaller than 12 too Switch Statement Switch statement is an alternative to long if-else-if ladders. The expression is checked for different cases and the one match is executed. break statement is used to move out of the switch. If the break is not used, the control will flow to all cases below it until break is found or switch COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 92 comes to an end. There is default case (optional) at the end of switch, if none of the case matches then default case is executed. Syntax: switch (expression) { case value1: // statement sequence break; case value2: // statement sequence break; . . . case valueN: // statement sequence break; default: // default statement sequence } Flow Diagram of Switch – case : COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 93 Page | 94 COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Example: Csharp • // C# example for switch case using System; public class GFG { public static void Main(String[] args) { int number = 30; switch(number) { case 10: Console.WriteLine("case 10"); break; case 20: Console.WriteLine("case 20"); break; case 30: Console.WriteLine("case 30"); break; default: Console.WriteLine("None matches"); break; } } } Output: case 30 COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 95 Nested switch Nested Switch case are allowed in C# . In this case, switch is present inside other switch case. Inner switch is present in one of the cases in parent switch. Example: • Page | 96 Csharp // C# example for nested switch case using System; public class GFG { public static void Main(String[] args) { int j = 5; switch (j) { case 5: Console.WriteLine(5); switch (j - 1) { case 4: Console.WriteLine(4); switch (j - 2) { case 3: Console.WriteLine(3); break; } break; } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) break; case 10: Console.WriteLine(10); break; case 15: Console.WriteLine(15); break; default: Console.WriteLine(100); break; } } } Output: 5 4 3 SWITCH STATEMENT IN C# In C#, Switch statement is a multiway branch statement. It provides an efficient way to transfer the execution to different parts of a code based on the value of the expression. The switch expression is of integer type such as int, char, byte, or short, or of an enumeration type, or of string type. The expression is checked for different cases and the one match is executed. Syntax: switch (expression) { case value1: // statement sequence break; case value2: // statement sequence break; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 97 . . . case valueN: // statement sequence break; default: // default statement sequence } Flow Chart: IMPORTANT POINTS TO REMEMBER: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 98 • In C#, duplicate case values are not allowed. • The data type of the variable in the switch and value of a case must be of the same type. • The value of a case must be a constant or a literal. Variables are not allowed. • The break in switch statement is used to terminate the current sequence. • The default statement is optional and it can be used anywhere inside the switch statement. • Multiple default statements are not allowed. Example: // C# program to illustrate // switch case statement using System; public class GFG { // Main Method public static void Main(String[] args) { int nitem = 5; switch (nitem) { case 1: Console.WriteLine("case 1"); break; case 5: Console.WriteLine("case 5"); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 99 break; case 9: Console.WriteLine("case 9"); break; default: Console.WriteLine("No match found"); break; } } } Output: case 5 WHY DO WE USE SWITCH STATEMENTS INSTEAD OF IF-ELSE STATEMENTS? We use a switch statement instead of if-else statements because if-else statement only works for a small number of logical evaluations of a value. If you use if-else statement for a larger number of possible conditions then, it takes more time to write and also become difficult to read. Example: Using if-else-if statement // C# program to illustrate // if-else statement using System; class GFG { // Main Method public static void Main(String[] args) COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 100 { // taking two strings value string topic; string category; // taking topic name topic = "Inheritance"; // using compare function of string class if ((String.Compare(topic, "Introduction to C#") == 0) || (String.Compare(topic, "Variables") == 0) || (String.Compare(topic, "Data Types") == 0)) { category = "Basic"; } // using compare function of string class else if ((String.Compare(topic, "Loops") == 0) || (String.Compare(topic, "If Statements") == 0) || (String.Compare(topic, "Jump Statements") == 0)) { category = "Control Flow"; } // using compare function of string class else if ((String.Compare(topic, "Class & Object") == 0) || (String.Compare(topic, "Inheritance") == 0) || COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 101 (String.Compare(topic, "Constructors") == 0)) { category = "OOPS Concept"; } else { category = "Not Mentioned"; } System.Console.Write("Category is " + category); } } Output: Category is OOPS Concept Explanation: As shown in the above program the code is not excessive but, it looks complicated to read and took more time to write. So we use a switch statement to save time and write optimized code. Using switch statement will provide a better readability of code. Example: Using Switch Statement // C# program to illustrate // switch statement using System; class GFG { // Main Method public static void Main(String[] args) COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 102 { // taking two strings value string topic; string category; // taking topic name topic = "Inheritance"; // using switch Statement switch(topic) { case "Introduction to C#": case "Variables": case "Data Types": category = "Basic"; break; case "Loops": case"If Statements": case"Jump Statements": category = "Control Flow"; break; case "Class & Object": case "Inheritance": COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 103 case "Constructors": category = "OOPS Concept"; break; // default case default: category = "Not Mentioned"; break; } System.Console.Write("Category is " + category); } } Output: Category is OOPS Concept USING GOTO IN THE SWITCH STATEMENT You can also use goto statement in place of the break in the switch statement. Generally, we use a break statement to exit from the switch statement. But in some situations, the default statement is required to be executed, so we use the goto statement. It allows executing default condition in the switch statement. The goto statement is also used to jump to a labeled location in C# program. Example: // C# program to illustrate the // use of goto in switch statement using System; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 104 public class GFG { // Main Method public static void Main(String[] args) { int greeting = 2; switch (greeting) { case 1: Console.WriteLine("Hello"); goto default; case 2: Console.WriteLine("Bonjour"); goto case 3; case 3: Console.WriteLine("Namaste"); goto default; default: Console.WriteLine("Entered value is: " + greeting); break; } } } Output: Bonjour Namaste COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 105 Entered value is: 2 Explanation: In the above program, the goto statement is used in a switch statement. Here first the case 2, i.e Bonjour is printed because the switch contains the value of greeting is 2, then the control transfers to the case 3 due to the presence of goto statement, so it prints Namaste and in last the control transfer to the default condition and print Entered value is: 2. Note: You can also use continue in place of a break in switch statement if your switch statement is a part of a loop, then continue statement will cause execution to return instantly to the starting of the loop. LOOPS IN C# Looping in a programming language is a way to execute a statement or a set of statements multiple times depending on the result of the condition to be evaluated to execute statements. The result condition should be true to execute statements within loops. Loops are mainly divided into two categories: Entry Controlled Loops: The loops in which condition to be tested is present in beginning of loop body are known as Entry Controlled Loops. while loop and for loop are entry controlled loops. 1. while loop The test condition is given in the beginning of the loop and all statements are executed till the given boolean condition satisfies when the condition becomes false, the control will be out from the while loop. Syntax: while (boolean condition) { loop statements... } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 106 Flowchart: Page | 107 Example: // C# program to illustrate while loop using System; class whileLoopDemo { public static void Main() { int x = 1; // Exit when x becomes greater than 4 COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) while (x <= 4) { Console.WriteLine("GeeksforGeeks"); // Increment the value of x for // next iteration x++; } } } Output: GeeksforGeeks GeeksforGeeks GeeksforGeeks GeeksforGeeks 2. for loop for loop has similar functionality as while loop but with different syntax. for loops are preferred when the number of times loop statements are to be executed is known beforehand. The loop variable initialization, condition to be tested, and increment/decrement of the loop variable is done in one line in for loop thereby providing a shorter, easy to debug structure of looping. for (loop variable initialization ; testing condition; increment / decrement) { // statements to be executed } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 108 Flowchart: Page | 109 1. Initialization of loop variable: Th expression / variable controlling the loop is initialized here. It is the starting point of for loop. An already declared variable can be used or a variable can be declared, local to loop only. 2. Testing Condition: The testing condition to execute statements of loop. It is used for testing the exit condition for a loop. It must return a boolean value true or false. When the condition became false the control will be out from the loop and for loop ends. 3. Increment / Decrement: The loop variable is incremented/decremented according to the requirement and the control then shifts to the testing condition again. Note: Initialization part is evaluated only once when the for loop starts. Example: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) // C# program to illustrate for loop. using System; class forLoopDemo { public static void Main() { // for loop begins when x=1 // and runs till x <=4 for (int x = 1; x <= 4; x++) Console.WriteLine("GeeksforGeeks"); } } Output: GeeksforGeeks GeeksforGeeks GeeksforGeeks GeeksforGeeks Exit Controlled Loops: The loops in which the testing condition is present at the end of loop body are termed as Exit Controlled Loops. do-while is an exit controlled loop. Note: In Exit Controlled Loops, loop body will be evaluated for at-least one time as the testing condition is present at the end of loop body. 1. do-while loop do while loop is similar to while loop with the only difference that it checks the condition after executing the statements, i.e it will execute the loop body one time for sure because it checks the condition after executing the statements. Syntax : do { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 110 statements.. }while (condition); Flowchart: Page | 111 Example: // C# program to illustrate do-while loop using System; class dowhileloopDemo { public static void Main() { int x = 21; do { // The line will be printed even // if the condition is false COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Console.WriteLine("GeeksforGeeks"); x++; } while (x < 20); } } Output: GeeksforGeeks Infinite Loops: The loops in which the test condition does not evaluate false ever tend to execute statements forever until an external force is used to end it and thus they are known as infinite loops. Example: // C# program to demonstrate infinite loop using System; class infiniteLoop { public static void Main() { // The statement will be printed // infinite times for(;;) Console.WriteLine("This is printed infinite times"); } } Output: This is printed infinite times COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 112 This is printed infinite times This is printed infinite times This is printed infinite times This is printed infinite times This is printed infinite times This is printed infinite times .......... Nested Loops: When loops are present inside the other loops, it is known as nested loops. Example: // C# program to demonstrate nested loops using System; class nestedLoops { public static void Main() { // loop within loop printing GeeksforGeeks for(int i = 2; i < 3; i++) for(int j = 1; j < i; j++) Console.WriteLine("GeeksforGeeks"); } } Output: GeeksforGeeks continue statement: continue statement is used to skip over the execution part of loop on a certain condition and move the flow to next updation part. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 113 Flowchart: Page | 114 Example: // C# program to demonstrate continue statement using System; class demoContinue { public static void Main() { // GeeksforGeeks is printed only 2 times // because of continue statement for(int i = 1; i < 3; i++) { if(i == 2) continue; Console.WriteLine("GeeksforGeeks"); } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) } } Output: GeeksforGeeks C# | JUMP STATEMENTS (BREAK, CONTINUE, GOTO, RETURN AND THROW) In C#, Jump statements are used to transfer control from one point to another point in the program due to some specified code while executing the program. There are five keywords in the Jump Statements: • break • continue • goto • return • throw break statement The break statement is used to terminate the loop or statement in which it present. After that, the control will pass to the statements that present after the break statement, if available. If the break statement present in the nested loop, then it terminates only those loops which contains break statement. Flowchart: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 115 Page | 116 Example: // C# program to illustrate the // use of break statement using System; class Geeks { // Main Method static public void Main() { // GeeksforGeeks is printed only 2 times COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) // because of break statement for (int i = 1; i < 4; i++) { if (i == 3) break; Console.WriteLine("GeeksforGeeks"); } } } Output: GeeksforGeeks GeeksforGeeks continue statement This statement is used to skip over the execution part of the loop on a certain condition. After that, it transfers the control to the beginning of the loop. Basically, it skips its following statements and continues with the next iteration of the loop. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 117 Example: // C# program to illustrate the // use of continue statement using System; class Geeks { // Main Method public static void Main() { // This will skip 4 to print for (int i = 1; i <= 10; i++) { // if the value of i becomes 4 then // it will skip 4 and send the // transfer to the for loop and // continue with 5 if (i == 4) continue; Console.WriteLine(i); } } } Output: 1 COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 118 2 3 5 6 Page | 119 7 8 9 10 goto statement This statement is used to transfer control to the labeled statement in the program. The label is the valid identifier and placed just before the statement from where the control is transferred. Example: // C# program to illustrate the // use of goto statement using System; class Geeks { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) // Main Method static public void Main() { int number = 20; switch (number) { case 5: Console.WriteLine("case 5"); break; case 10: Console.WriteLine("case 10"); break; case 20: Console.WriteLine("case 20"); // goto statement transfer // the control to case 5 goto case 5; default: Console.WriteLine("No match found"); break; } } } Output: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 120 case 20 case 5 return statement This statement terminates the execution of the method and returns the control to the calling method. It returns an optional value. If the type of method is void, then the return statement can be excluded. Example: // C# program to illustrate the // use of return statement using System; class Geeks { // creating simple addition function static int Addition(int a) { // add two value and // return the result of addition int add = a + a; // using return statement return add; } // Main Method static public void Main() { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 121 int number = 2; // calling addition function int result = Addition(number); Console.WriteLine("The addition is {0}", result); } } Output: The addition is 4 throw statement This is used to create an object of any valid exception class with the help of new keyword manually. The valid exception must be derived from the Exception class. Example: // C# Program to illustrate the use // of throw keyword using System; class Geeks { // takinmg null in the string static string sub = null; // method to display subject name static void displaysubject(string sub1) { if (sub1 == null) COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 122 throw new NullReferenceException("Exception Message"); } Page | 123 // Main Method static void Main(string[] args) { // using try catch block to // handle the Exception try { // calling the static method displaysubject(sub); } catch(Exception exp) { Console.WriteLine(exp.Message ); } } } Output: Exception Message COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Class and Object C# | CLASS AND OBJECT Class and Object are the basic concepts of Object-Oriented Programming which revolve around the real-life entities. A class is a user-defined blueprint or prototype from which objects are created. Basically, a class combines the fields and methods(member function which defines Page | 124 actions) into a single unit. In C#, classes support polymorphism, inheritance and also provide the concept of derived classes and base classes. Declaration of class Generally, a class declaration contains only keyword class, followed by an identifier(name) of the class. But there are some optional attributes that can be used with class declaration according to the application requirement. In general, class declarations can include these components, in order: • Modifiers: A class can be public or internal etc. By default modifier of class is internal. • Keyword class: A class keyword is used to declare the type class. • Class Identifier: The variable of type class is provided. The identifier(or name of class) should begin with a initial letter which should be capitalized by convention. • Base class or Super class: The name of the class’s parent (superclass), if any, preceded by the : (colon). This is optional. • Interfaces: A comma-separated list of interfaces implemented by the class, if any, preceded by the : (colon). A class can implement more than one interface. This is optional. • Body: The class body is surrounded by { } (curly braces). Constructors in class are used for initializing new objects. Fields are variables that provide the state of the class and its objects, and methods are used to implement the behavior of the class and its objects. Example: // declaring public class public class Geeks { // field variable public int a, b; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) // member function or method public void display() { Console.WriteLine(“Class & Objects in C#”); } } Objects It is a basic unit of Object-Oriented Programming and represents the real-life entities. A typical C# program creates many objects, which as you know, interact by invoking methods. An object consists of : • State: It is represented by attributes of an object. It also reflects the properties of an object. • Behavior: It is represented by methods of an object. It also reflects the response of an object with other objects. • Identity: It gives a unique name to an object and enables one object to interact with other objects. Consider Dog as an object and see the below diagram for its identity, state, and behavior. Objects correspond to things found in the real world. For example, a graphics program may have objects such as “circle”, “square”, “menu”. An online shopping system might have objects such as “shopping cart”, “customer”, and “product”. Declaring Objects (Also called instantiating a class) When an object of a class is created, the class is said to be instantiated. All the instances share the attributes and the behavior of the class. But the values of those attributes, i.e. the state are unique for each object. A single class may have any number of instances. Example: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 125 Page | 126 As we declare variables like (type name;). This notifies the compiler that we will use the name to refer to data whose type is type. With a primitive variable, this declaration also reserves the proper amount of memory for the variable. So for reference variable, type must be strictly a concrete class name. Dog tuffy; If we declare a reference variable(tuffy) like this, its value will be undetermined(null) until an object is actually created and assigned to it. Simply declaring a reference variable does not create an object. Initializing an object The new operator instantiates a class by allocating memory for a new object and returning a reference to that memory. The new operator also invokes the class constructor. Example: // C# program to illustrate the // Initialization of an object using System; // Class Declaration COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) public class Dog { // Instance Variables String name; String breed; int age; String color; // Constructor Declaration of Class public Dog(String name, String breed, int age, String color) { this.name = name; this.breed = breed; this.age = age; this.color = color; } // Property 1 public String getName() { return name; } // Property 2 public String getBreed() { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 127 return breed; } // Property 3 public int getAge() { return age; } // Property 4 public String getColor() { return color; } // Method 1 public String toString() { return ("Hi my name is " + this.getName() + ".\nMy breed, age and color are " + this.getBreed() + ", " + this.getAge() + ", " + this.getColor()); } // Main Method public static void Main(String[] args) { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 128 // Creating object Dog tuffy = new Dog("tuffy", "papillon", 5, "white"); Console.WriteLine(tuffy.toString()); } } Output: Hi my name is tuffy. My breed, age and color are papillon, 5, white Explanation: This class contains a single constructor. We can recognize a constructor because its declaration uses the same name as the class and it has no return type. The C# compiler differentiates the constructors based on the number and the type of the arguments. The constructor in the Dog class takes four arguments. The following statement provides “tuffy”, ”papillon”, 5, ”white” as values for those arguments: Dog tuffy = new Dog("tuffy", "papillon", 5, "white"); The result of executing this statement can be illustrated as : Constructors C# | CONSTRUCTORS A constructor is a special method of the class which gets automatically invoked whenever an instance of the class is created. Like methods, a constructor also contains the collection of instructions that are executed at the time of Object creation. It is used to assign initial values to the data members of the same class. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 129 Example : class Geek { ....... Page | 130 // Constructor public Geek() {} ....... } // an object is created of Geek class, // So above constructor is called Geek obj = new Geek(); IMPORTANT POINTS TO REMEMBER ABOUT CONSTRUCTORS • Constructor of a class must have the same name as the class name in which it resides. • A constructor can not be abstract, final, and Synchronized. • Within a class, you can create only one static constructor. • A constructor doesn’t have any return type, not even void. • A static constructor cannot be a parameterized constructor. • A class can have any number of constructors. • Access modifiers can be used in constructor declaration to control its access i.e which other class can call the constructor. TYPES OF CONSTRUCTOR 1. Default Constructor 2. Parameterized Constructor 3. Copy Constructor 4. Private Constructor 5. Static Constructor Default Constructor COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) A constructor with no parameters is called a default constructor. A default constructor has every instance of the class to be initialized to the same values. The default constructor initializes all numeric fields to zero and all string and object fields to null inside a class. Example : • C# // C# Program to illustrate calling // a Default constructor using System; namespace DefaultConstructorExample { class Geek { int num; string name; // this would be invoked while the // object of that class created. Geek() { Console.WriteLine("Constructor Called"); } // Main Method public static void Main() { // this would invoke default // constructor. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 131 Geek geek1 = new Geek(); // Default constructor provides // the default values to the // int and object as 0, null // Note: // It Give Warning because // Fields are not assign Console.WriteLine(geek1.name); Console.WriteLine(geek1.num); } } } Output : Constructor Called 0 Note : This will also show some warnings as follows: prog.cs(8, 6): warning CS0649: Field `DefaultConstructorExample.Geek.num' is never assigned to, and will always have its default value `0' prog.cs(9, 9): warning CS0649: Field `DefaultConstructorExample.Geek.name' is never assigned to, and will always have its default value `null' Parameterized Constructor A constructor having at least one parameter is called as parameterized constructor. It can initialize each instance of the class to different values. Example : • C# // C# Program to illustrate calling of COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 132 // parameterized constructor. using System; namespace ParameterizedConstructorExample { class Geek { // data members of the class. String name; int id; // parameterized constructor would // initialized data members with // the values of passed arguments // while object of that class created. Geek(String name, int id) { this.name = name; this.id = id; } // Main Method public static void Main() { // This will invoke parameterized // constructor. Geek geek1 = new Geek("GFG", 1); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 133 Console.WriteLine("GeekName = " + geek1.name + " and GeekId = " + geek1.id); } Page | 134 } } Output : GeekName = GFG and GeekId = 1 COPY CONSTRUCTOR This constructor creates an object by copying variables from another object. Its main use is to initialize a new instance to the values of an existing instance. Example : • C# // C# Program to illustrate calling // a Copy constructor using System; namespace copyConstructorExample { class Geeks { private string month; private int year; // declaring Copy constructor public Geeks(Geeks s) { month = s.month; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) year = s.year; } // Instance constructor public Geeks(string month, int year) { this.month = month; this.year = year; } // Get details of Geeks public string Details { get { return "Month: " + month.ToString() + "\nYear: " + year.ToString(); } } // Main Method public static void Main() { // Create a new Geeks object. Geeks g1 = new Geeks("June", 2018); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 135 // here is g1 details is copied to g2. Geeks g2 = new Geeks(g1); Console.WriteLine(g2.Details); } } } Output : Month: June Year: 2018 PRIVATE CONSTRUCTOR If a constructor is created with private specifier is known as Private Constructor. It is not possible for other classes to derive from this class and also it’s not possible to create an instance of this class. POINTS TO REMEMBER: • It is the implementation of a singleton class pattern. • use private constructor when we have only static members. • Using private constructor, prevents the creation of the instances of that class. Example : • C# // C# Program to illustrate calling // a Private constructor using System; namespace privateConstructorExample { public class Geeks { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 136 // declare private Constructor private Geeks() { Page | 137 } // declare static variable field public static int count_geeks; // declare static method public static int geeks_Count() { return ++count_geeks; } // Main Method public static void Main() { // If you uncomment the following // statement, it will generate // an error because the constructor // is unaccessible: // Geeks s = new Geeks(); // Error Geeks.count_geeks = 99; // Accessing without any COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) // instance of the class Geeks.geeks_Count(); Console.WriteLine(Geeks.count_geeks); // Accessing without any // instance of the class Geeks.geeks_Count(); Console.WriteLine(Geeks.count_geeks); } } } Output : 100 101 STATIC CONSTRUCTOR Static Constructor has to be invoked only once in the class and it has been invoked during the creation of the first reference to a static member in the class. A static constructor is initialized static fields or data of the class and to be executed only once. POINTS TO REMEMBER: • It can’t be called directly. • When it is executing then the user has no control. • It does not take access modifiers or any parameters. • It is called automatically to initialize the class before the first instance created. Example : • C# COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 138 // C# Program to illustrate calling // a Static constructor using System; namespace staticConstructorExample { class geeks { // It is invoked before the first // instance constructor is run. static geeks() { // The following statement produces // the first line of output, // and the line occurs only once. Console.WriteLine("Static Constructor"); } // Instance constructor. public geeks(int i) { Console.WriteLine("Instance Constructor " + i); } // Instance method. public string geeks_detail(string name, int id) { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 139 return "Name:" + name + " id:" + id; } // Main Method public static void Main() { // Here Both Static and instance // constructors are invoked for // first instance geeks obj = new geeks(1); Console.WriteLine(obj.geeks_detail("GFG", 1)); // Here only instance constructor // will be invoked geeks obj1 = new geeks(2); Console.WriteLine(obj1.geeks_detail("GeeksforGeeks", 2)); } } } Output : Static Constructor Instance Constructor 1 Name:GFG id:1 Instance Constructor 2 COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 140 Name:GeeksforGeeks id:2 Inheritance C# | INHERITANCE Inheritance is an important pillar of OOP(Object Oriented Programming). It is the mechanism in Page | 141 C# by which one class is allowed to inherit the features(fields and methods) of another class. Important terminology: • Super Class: The class whose features are inherited is known as super class(or a base class or a parent class). • Sub Class: The class that inherits the other class is known as subclass(or a derived class, extended class, or child class). The subclass can add its own fields and methods in addition to the superclass fields and methods. • Reusability: Inheritance supports the concept of “reusability”, i.e. when we want to create a new class and there is already a class that includes some of the code that we want, we can derive our new class from the existing class. By doing this, we are reusing the fields and methods of the existing class. HOW TO USE INHERITANCE The symbol used for inheritance is :. Syntax: class derived-class : base-class { // methods and fields . . } Example: In below example of inheritance, class GFG is a base class, class GeeksforGeeks is a derived class which extends GFG class and class Sudo is a driver class to run program. // C# program to illustrate the // concept of inheritance using System; namespace ConsoleApplication1 { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) // Base class class GFG { // data members public string name; public string subject; // public method of base class public void readers(string name, string subject) { this.name = name; this.subject = subject; Console.WriteLine("Myself: " + name); Console.WriteLine("My Favorite Subject is: " + subject); } } // inheriting the GFG class using : class GeeksforGeeks : GFG { // constructor of derived class public GeeksforGeeks() { Console.WriteLine("GeeksforGeeks"); } } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 142 // Driver class class Sudo { // Main Method static void Main(string[] args) { // creating object of derived class GeeksforGeeks g = new GeeksforGeeks(); // calling the method of base class // using the derived class object g.readers("Kirti", "C#"); } } } Output: GeeksforGeeks Myself: Kirti My Favorite Subject is: C# TYPES OF INHERITANCE IN C# Below are the different types of inheritance which is supported by C# in different combinations. 1. Single Inheritance: In single inheritance, subclasses inherit the features of one superclass. In image below, the class A serves as a base class for the derived class B. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 143 Page | 144 2. Multilevel Inheritance: In Multilevel Inheritance, a derived class will be inheriting a base class and as well as the derived class also act as the base class to other class. In below image, class A serves as a base class for the derived class B, which in turn serves as a base class for the derived class C. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 145 3. Hierarchical Inheritance: In Hierarchical Inheritance, one class serves as a superclass (base class) for more than one subclass. In below image, class A serves as a base class for the derived class B, C, and D. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) 4. Multiple Inheritance(Through Interfaces):In Multiple inheritance, one class can have more than one superclass and inherit features from all parent classes. Please note that C# does not support multiple inheritance with classes. In C#, we can achieve multiple inheritance only through Interfaces. In the image below, Class C is derived from interface A and B. 5. Hybrid Inheritance(Through Interfaces): It is a mix of two or more of the above types of inheritance. Since C# doesn’t support multiple inheritance with classes, the hybrid inheritance is also not possible with classes. In C#, we can achieve hybrid inheritance only through Interfaces. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 146 Page | 147 IMPORTANT FACTS ABOUT INHERITANCE IN C# • Default Superclass: Except Object class, which has no superclass, every class has one and only one direct superclass(single inheritance). In the absence of any other explicit superclass, every class is implicitly a subclass of Object class. • Superclass can only be one: A superclass can have any number of subclasses. But a subclass can have only one superclass. This is because C# does not support multiple inheritance with classes. Although with interfaces, multiple inheritance is supported by C#. • Inheriting Constructors: A subclass inherits all the members (fields, methods) from its superclass. Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass. • Private member inheritance: A subclass does not inherit the private members of its parent class. However, if the superclass has properties(get and set methods) for accessing its private fields, then a subclass can inherit. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Encapsulation C# | ENCAPSULATION Encapsulation is defined as the wrapping up of data under a single unit. It is the mechanism that binds together code and the data it manipulates. In a different way, encapsulation is a protective shield that prevents the data from being accessed by the code outside this shield. • Technically in encapsulation, the variables or data of a class are hidden from any other class and can be accessed only through any member function of own class in which they are declared. • As in encapsulation, the data in a class is hidden from other classes, so it is also known as data-hiding. • Encapsulation can be achieved by: Declaring all the variables in the class as private and using C# Properties in the class to set and get the values of variables. Example: // C# program to illustrate encapsulation using System; public class DemoEncap { // private variables declared // these can only be accessed by // public methods of class private String studentName; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 148 private int studentAge; // using accessors to get and // set the value of studentName public String Name { get { return studentName; } set { studentName = value; } } // using accessors to get and // set the value of studentAge public int Age { get { return studentAge; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 149 } set { studentAge = value; } } } // Driver Class class GFG { // Main Method static public void Main() { // creating object DemoEncap obj = new DemoEncap(); // calls set accessor of the property Name, // and pass "Ankita" as value of the // standard field 'value' obj.Name = "Ankita"; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 150 // calls set accessor of the property Age, // and pass "21" as value of the // standard field 'value' obj.Age = 21; // Displaying values of the variables Console.WriteLine("Name: " + obj.Name); Console.WriteLine("Age: " + obj.Age); } } Output: Name: Ankita Age: 21 Explanation: In the above program the class DemoEncap is encapsulated as the variables are declared as private. To access these private variables we are using the Name and Age accessors which contains the get and set method to retrieve and set the values of private fields. Accessors are defined as public so that they can access in other class. ADVANTAGES OF ENCAPSULATION: • Data Hiding: The user will have no idea about the inner implementation of the class. It will not be visible to the user that how the class is stored values in the variables. He only knows that we are passing the values to accessors and variables are getting initialized to that value. • Increased Flexibility: We can make the variables of the class as read-only or write-only depending on our requirement. If we wish to make the variables as read-only then we have to only use Get Accessor in the code. If we wish to make the variables as write-only then we have to only use Set Accessor. • Reusability: Encapsulation also improves the re-usability and easy to change with new requirements. • Testing code is easy: Encapsulated code is easy to test for unit testing. Abstraction C# | ABSTRACTION COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 151 Data Abstraction is the property by virtue of which only the essential details are exhibited to the user. The trivial or the non-essentials units aren’t exhibited to the user. Data Abstraction may also be defined as the process of identifying only the required characteristics of an object ignoring the irrelevant details. The properties and behaviors of an object differentiate it from other objects of similar type and also help in classifying/grouping the objects. Example: Consider a real-life scenario of withdrawing money from ATM. The user only knows that in ATM machine first enter ATM card, then enter the pin code of ATM card, and then enter the amount which he/she wants to withdraw and at last, he/she gets their money. The user does not know about the inner mechanism of the ATM or the implementation of withdrawing money etc. The user just simply know how to operate the ATM machine, this is called abstraction. In C# abstraction is achieved with the help of Abstract classes. ABSTRACT CLASSES • An abstract class is declared with the help of abstract keyword. • In C#, you are not allowed to create objects of the abstract class. Or in other words, you cannot use the abstract class directly with the new operator. • Class that contains the abstract keyword with some of its methods(not all abstract method) is known as an Abstract Base Class. • Class that contains the abstract keyword with all of its methods is known as pure Abstract Base Class. • You are not allowed to declare the abstract methods outside the abstract class. • You are not allowed to declare abstract class as Sealed Class. USING ABSTRACT CLASSES AND ABSTRACT METHODS WITH AN EXAMPLE There are situations in which we want to define a superclass that declares the structure of a given abstraction without providing a complete implementation of every method. That is, sometimes we want to create a superclass that only defines a generalized form that will be shared by all of its subclasses, leaving it to each subclass to fill in the details. Consider a classic “shape” example, perhaps used in a computer-aided design system or game simulation. The base type is “shape” and each shape has a color, size and so on. From this, specific types of shapes are derived(inherited)-circle, square, triangle and so on – each of which may have additional characteristics and behaviors. For example, certain shapes can be flipped. Some behaviors may be different, such as when you want to calculate the area of a square. Example: // C# program to calculate the area COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 152 // of a square using the concept of // data abstraction using System; namespace Demoabstraction { // abstract class abstract class Shape { // abstract method public abstract int area(); } // square class inherting // the Shape class class Square : Shape { // private data member private int side; // method of square class public Square(int x = 0) { side = x; } // overriding of the abstract method of Shape COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 153 // class using the override keyword public override int area() { Console.Write("Area of Square: "); return (side * side); } } // Driver Class class GFG { // Main Method static void Main(string[] args) { // creating reference of Shape class // which refer to Square class instance Shape sh = new Square(4); // calling the method double result = sh.area(); Console.Write("{0}", result); } } } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 154 Output: Area of Square: 16 ENCAPSULATION VS DATA ABSTRACTION • Encapsulation is data hiding(information hiding) while Abstraction is detail hiding(implementation hiding). • While encapsulation groups together data and methods that act upon the data, data abstraction deals with exposing to the user and hiding the details of implementation. ADVANTAGES OF ABSTRACTION • It reduces the complexity of viewing the things. • Avoids code duplication and increases reusability. • Helps to increase security of an application or program as only important details are provided to the user. Methods C# | METHODS Methods are generally the block of codes or statements in a program that gives the user the ability to reuse the same code which ultimately saves the excessive use of memory, acts as a time saver and more importantly, it provides a better readability of code. So basically, a method is a collection of statements that perform some specific task and return the result to the caller. A method can also perform some specific task without returning anything. Example : // Method Name --> GetCircleArea() // Return Type ---> double static double GetCircleArea(double radius) { const float pi = 3.14F; double area = pi * radius * radius; return area; } METHOD DECLARATION COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 155 Method declaration means the way to construct method including its naming. Syntax : <Access_Modifier> <return_type> <method_name>([<param_list>]) Page | 156 IN C# A METHOD DECLARATION CONSISTS OF THE FOLLOWING COMPONENTS AS FOLLOWS: • Modifier : It defines access type of the method i.e. from where it can be accessed in your application. In C# there are Public, Protected, Private access modifiers. • Name of the Method : It describes the name of the user defined method by which the user calls it or refer it. Eg. GetName() • Return type: It defines the data type returned by the method. It depends upon user as it may also return void value i.e return nothing • Body of the Method : It refers to the line of code of tasks to be performed by the method during its execution. It is enclosed between braces. • Parameter list : Comma separated list of the input parameters are defined, preceded with their data type, within the enclosed parenthesis. If there are no parameters, then empty parentheses () have to use out. Method Signature : Method Signature is defined by mainly two parameters(number of parameters, type of the parameters and order of the parameters), One of them is Method Name and second one is its Parameter list. Method Naming : Name of a method or a function in any programming language whether in COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) C++ or Java or C# holds great importance and is mainly used in order to call that method for its execution. For example, findSum, computeMax, setX and getX etc. There are certain pre-defined rules for naming methods which a user should follow : • The method name must be some kind of Noun or a verb. • It’s naming should be done in such a way that it must describe the purpose of that method. • The first letter of the method name can be either a small letter or a Capital letter, however, it is recommended to use the capital one. These rules are not mandatory, but recommendable. Generally, a method has a unique name within the class in which it is defined but sometime a method might have the same name as other method names within the same class as method overloading is allowed in C#. The Method Body : As discussed above the body of the method consists of statements of code which a user wants to perform. After the method has been declared, it is dependent on the user whether to define its implementation or not. Not writing any implementation, makes the method not to perform any task. However, when the user wants to perform certain tasks using method then it must write the statements for execution in the body of the method. The below syntax describes the basic structure of the method body : Syntax : <return_type> <method_name>(<parameter_list>) { // Implementation of the method code goes here..... } METHOD CALLING Method Invocation or Method Calling is done when the user wants to execute the method. The method needs to be called for using its functionality. A method returns to the code that invoked it when: • It completes all the statements in the method • It reaches a return statement • Throws an exception Example : In the code below, a method named Sum() is called. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 157 • CSHARP // C# program to illustrate // method calling using System; namespace ConsoleApplication1 { class Geeks { // Here Sum() method asks for two // parameters from the user and // calculates the sum of these // and finally returns the result. static int Sum(int x, int y) { // there are two local variables // 'a' and 'b' where 'a' is assigned // the value of parameter 'x' and // 'b' is assigned the value of // parameter 'y' int a = x; int b = y; // The local variable calculates // the sum of 'a' and 'b' // and returns the result // which is of 'int' type. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 158 int result = a + b; return result; } // Main Method static void Main(string[] args) { int a = 12; int b = 23; // Method Sum() is invoked and // the returned value is stored // in the local variable say 'c' int c = Sum(a, b); // Display Result Console.WriteLine("The Value of the sum is " + c); } } } Output : The Value of the sum is 35 METHOD PARAMETERS There might be certain situations the user want to execute a method but sometimes that method requires some value inputs in order to execute and complete its tasks. These input values are known as Parameters in a computer language terms. Now, these parameters can be either int, long or float or double or char. However, it depends upon the user requirements. The methods in COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 159 C# can be classified into different categories based on return type as well as input parameters. • Example Program Without Parameters & Without Return Type • CSHARP // C# program to illustrate method Without // Parameters & Without Return Type using System; namespace ConsoleApplication2 { class Geeks { // Here the method 'PrintSentence()' // neither takes any parameter nor // returns any value. It simply performs // the required operations and prints // the result within it. static void PrintSentence() { Console.WriteLine("No parameters and return type void"); } // Main Method static void Main(string[] args) { // Method Invoking or Method calling PrintSentence(); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 160 } } } Page | 161 • Output : No parameters and return type void • Example Program Without Parameters & With Return Value Type • CSHARP // C# program to illustrate the method Without // Parameters & With Return Value Type using System; namespace ConsoleApplication3 { class Geeks { // This method takes no parameter, // however returns the result obtained static int sum() { int a = 78, b = 70, add; add = a + b; return add; } // Main Method static void Main(string[] args) { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) // Here the calling variable // is 'getresult' int getresult = sum(); // Printing the value of // 'getresult' variable Console.WriteLine(getresult); } } } • Output : 148 • Example Program With Parameters & Without Return Value Type • CSHARP // C# program to illustrate Method With // Parameters & Without Return Value Type using System; namespace ConsoleApplication3 { class Geeks { // This method take the side of // the square as a parameter and // after obtaining the result, // it simply print it without // returning anything.. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 162 static void perimeter(int p) { // Displaying the perimeter // of the square Console.WriteLine("Perimeter of the Square is " + 4 * p); } // Main Method static void Main(string[] args) { // side of square int p = 5; // Method invoking perimeter(p); } } } • Output : Perimeter of the Square is 20 • Example Program With Parameters & With Return Value Type • CSHARP // C# program to illustrate Method With // Parameters & With Return Value Type COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 163 using System; namespace ConsoleApplication4 { class Geeks { // This method asks a number from // the user and using that it // calculates the factorial // of it and returns the result static int factorial(int n) { int f = 1; // Method to calculate the // factorial of a number for (int i = 1; i<= n; i++) { f = f * i; } return f; } // Main Method static void Main(string[] args) { int p = 4; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 164 // displaying result by calling the function Console.WriteLine("Factorial is : " + factorial(p)); } Page | 165 } } • Output : Factorial is: 24 ADVANTAGES OF USING THE METHODS: There are many advantages of using methods. Some of them are listed below: • It makes the program well structured. • Methods enhance the readability of the code. • It provides an effective way for the user to reuse the existing code. • It optimizes the execution time and memory space. Method Overloading C# | METHOD OVERLOADING Method Overloading is the common way of implementing polymorphism. It is the ability to redefine a function in more than one form. A user can implement function overloading by defining two or more functions in a class sharing the same name. C# can distinguish the methods with different method signatures. i.e. the methods can have the same name but with different parameters list (i.e. the number of the parameters, order of the parameters, and data types of the parameters) within the same class. • Overloaded methods are differentiated based on the number and type of the parameters passed as arguments to the methods. • You can not define more than one method with the same name, Order and the type of the arguments. It would be compiler error. • The compiler does not consider the return type while differentiating the overloaded method. But you cannot declare two methods with the same signature and different return type. It will throw a compile-time error. If both methods have the same parameter types, but different return type, then it is not possible. WHY DO WE NEED METHOD OVERLOADING? COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) If we need to do the same kind of the operation in different ways i.e. for different inputs. In the example described below, we are doing the addition operation for different inputs. It is hard to find many different meaningful names for single action. DIFFERENT WAYS OF DOING OVERLOADING METHODSMethod overloading can be done by changing: 1. The number of parameters in two methods. 2. The data types of the parameters of methods. 3. The Order of the parameters of methods. BY CHANGING THE NUMBER OF PARAMETERS • C# // C# program to demonstrate the function // overloading by changing the Number // of parameters using System; class GFG { // adding two integer values. public int Add(int a, int b) { int sum = a + b; return sum; } // adding three integer values. public int Add(int a, int b, int c) { int sum = a + b + c; return sum; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 166 } // Main Method public static void Main(String[] args) { // Creating Object GFG ob = new GFG(); int sum1 = ob.Add(1, 2); Console.WriteLine("sum of the two " + "integer value : " + sum1); int sum2 = ob.Add(1, 2, 3); Console.WriteLine("sum of the three " + "integer value : " + sum2); } } Output: sum of the two integer value : 3 sum of the three integer value : 6 BY CHANGING THE DATA TYPES OF THE PARAMETERS • C# // C# program to demonstrate the function // overloading by changing the Data types COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 167 // of the parameters using System; class GFG { Page | 168 // adding three integer values. public int Add(int a, int b, int c) { int sum = a + b + c; return sum; } // adding three double values. public double Add(double a, double b, double c) { double sum = a + b + c; return sum; } // Main Method public static void Main(String[] args) { // Creating Object GFG ob = new GFG(); int sum2 = ob.Add(1, 2, 3); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Console.WriteLine("sum of the three " + "integer value : " + sum2); double sum3 = ob.Add(1.0, 2.0, 3.0); Console.WriteLine("sum of the three " + "double value : " + sum3); } } Output: sum of the three integer value : 6 sum of the three double value : 6 BY CHANGING THE ORDER OF THE PARAMETERS • C# // C# program to demonstrate the function // overloading by changing the // Order of the parameters using System; class GFG { // Method public void Identity(String name, int id) { Console.WriteLine("Name1 : " + name + ", " + "Id1 : " + id); } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 169 // Method public void Identity(int id, String name) { Console.WriteLine("Name2 : " + name + ", " + "Id2 : " + id); } // Main Method public static void Main(String[] args) { // Creating Object GFG obj = new GFG(); obj.Identity("Akku", 1); obj.Identity(2, "Abby"); } } Output: Name1 : Akku, Id1 : 1 Name2 : Abby, Id2 : 2 What happens when method signature is same and the return type is different? The compiler will give error as the return value alone is not sufficient for the compiler to figure out which function it has to call. Only if both methods have different parameter types (so, they have the different signature), then Method overloading is possible. Example: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 170 • C# // C# program to show error when method signature // is the same and the return type is different. using System; class GFG { // adding two integer value. public int Add(int a, int b) { int sum = a + b; return sum; } // adding three integer value. public double Add(int a, int b) { double sum = a + b + 0.0; return sum; } // Main Method public static void Main(String[] args) { // Creating Object GFG ob = new GFG(); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 171 int sum1 = ob.Add(1, 2); Console.WriteLine("sum of the two " + "integer value :" + sum1); int sum2 = ob.Add(1, 2); Console.WriteLine("sum of the three " + "integer value :" + sum2); } } Compile Time Error: prog.cs(15,19): error CS0111: A member `GFG.Add(int, int)’ is already defined. Rename this member or use different parameter types prog.cs(7,16): (Location of the symbol related to previous error) Method Parameters C# | METHOD PARAMETERS Methods in C# are generally the block of codes or statements in a program which gives the user the ability to reuse the same code which ultimately saves the excessive use of memory, acts as a time saver and more importantly, it provides better readability of the code. So you can say a method is a collection of statements that perform some specific task and may/may not return the result to the caller. There might be certain situations the user want to execute a method but sometimes that method requires some valuable inputs in order to execute and complete its tasks. These input values are known as Parameters in computer language terms. C# CONTAINS THE FOLLOWING TYPES OF METHOD PARAMETERS: • Named Parameters • Ref Parameters • Out Parameters • Default or Optional Parameters • Dynamic Parameters • Value Parameters COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 172 • Params Named Parameters Using named parameters, you can specify the value of the parameter according to their names not their order in the method. Or in other words, it provides us a facility to not remember Page | 173 parameters according to their order. This concept is introduced in C# 4.0. It makes your program easier to understand when you are working with a larger number of parameters in your method. But always remember named parameters are always appear after fixed arguments, if you try to provide fixed argument after named parameter, then the compiler will throw an error. Example: // C# program to illustrate the // concept of the named parameters using System; public class GFG { // addstr contain three parameters public static void addstr(string s1, string s2, string s3) { string result = s1 + s2 + s3; Console.WriteLine("Final string is: " + result); } // Main Method static public void Main() { // calling the static method with named // parameters without any order COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) addstr(s1: "Geeks", s2: "for", s3: "Geeks"); } Page | 174 } Output: Final string is: GeeksforGeeks Ref Parameters The ref is a keyword in C# which is used for passing the value types by reference. Or we can say that if any changes made in this argument in the method will reflect in that variable when the control return to the calling method. The ref parameter does not pass the property. In ref parameters, it is necessary that the parameters should initialize before it pass to ref. The passing of value through the ref parameter is useful when the called method also needs to change the value of the passed parameter. Example: // C# program to illustrate the // concept of ref parameter using System; class GFG { // Main Method public static void Main() { // Assigning value string val = "Dog"; // Pass as a reference parameter COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) CompareValue(ref val); // Display the given value Console.WriteLine(val); } static void CompareValue(ref string val1) { // Compare the value if (val1 == "Dog") { Console.WriteLine("Matched!"); } // Assigning new value val1 = "Cat"; } } Output: Matched! Cat Out Parameters The out is a keyword in C# which is used for the passing the arguments to methods as a reference type. It is generally used when a method returns multiple values. The out parameter does not pass the property. It is not necessary to initialize parameters before it passes to out. The declaring of parameter throughout parameter is useful when a method returns multiple values. Example: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 175 // C# program to illustrate the // concept of out parameter using System; class GFG { // Main method static public void Main() { // Creating variable // without assigning value int num; // Pass variable num to the method // using out keyword AddNum(out num); // Display the value of num Console.WriteLine("The sum of" + " the value is: {0}",num); } // Method in which out parameter is passed // and this method returns the value of // the passed parameter COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 176 public static void AddNum(out int num) { num = 40; num += num; } } Output: The sum of the value is: 80 Default or Optional Parameters As the name suggests optional parameters are not compulsory parameters, they are optional. It helps to exclude arguments for some parameters. Or we can say in optional parameters, it is not necessary to pass all the parameters in the method. This concept is introduced in C# 4.0. Here, each and every optional parameter contains a default value which is the part of its definition. If we do not pass any arguments to the optional parameters, then it takes its default value. The optional parameters are always defined at the end of the parameter list. Or in other words, the last parameter of the method, constructor, etc. is the optional parameter. Example: // C# program to illustrate the // concept of optional parameters using System; class GFG { // This method contains two regular // parameters, i.e. ename and eid // And two optional parameters, i.e. // bgrp and dept static public void detail(string ename, COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 177 int eid, string bgrp = "A+", string dept = "Review-Team") { Console.WriteLine("Employee name: {0}", ename); Console.WriteLine("Employee ID: {0}", eid); Console.WriteLine("Blood Group: {0}", bgrp); Console.WriteLine("Department: {0}", dept); } // Main Method static public void Main() { // Calling the detail method detail("XYZ", 123); detail("ABC", 456, "B-"); detail("DEF", 789, "B+", "Software Developer"); } } Output: Employee name: XYZ Employee ID: 123 Blood Group: A+ Department: Review-Team COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 178 Employee name: ABC Employee ID: 456 Blood Group: BDepartment: Review-Team Employee name: DEF Employee ID: 789 Blood Group: B+ Department: Software Developer Dynamic Parameters In C# 4.0, a new type of parameters is introduced that is known as a dynamic parameter. Here the parameters pass dynamically means the compiler does not check the type of the dynamic type variable at compile-time, instead of this, the compiler gets the type at the run time. The dynamic type variable is created using a dynamic keyword. Example: // C# program to illustrate the concept // of the dynamic parameters using System; class GFG { // Method which contains dynamic parameter public static void mulval(dynamic val) { val *= val; Console.WriteLine(val); } // Main method COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 179 static public void Main() { // Calling mulval method mulval(30); } } Output: 900 Value Parameters It is a normal value parameter in a method or you can say the passing of value types by value. So when the variables are passed as value type they contain the data or value, not any reference. If you will make any changes in the value type parameter then it will not reflect the original value stored as an argument. Example: // C# program to illustrate value parameters using System; public class GFG { // Main Method static public void Main() { // The value of the parameter // is already assigned string str1 = "Geeks"; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 180 string str2 = "geeks"; string res = addstr(str1, str2); Console.WriteLine(res); } public static string addstr(string s1, string s2) { return s1 + s2; } } Output: Geeksgeeks Params It is useful when the programmer doesn’t have any prior knowledge about the number of parameters to be used. By using params you are allowed to pass any variable number of arguments. Only one params keyword is allowed and no additional Params will be allowed in function declaration after a params keyword. The length of params will be zero if no arguments will be passed. Example: // C# program to illustrate params using System; namespace Examples { class Geeks { // function containing params parameters public static int mulval(params int[] num) COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 181 { int res = 1; // foreach loop foreach(int j in num) { res *= j; } return res; } static void Main(string[] args) { // Calling mulval method int x = mulval(20, 49, 56, 69, 78); // show result Console.WriteLine(x); } } } Output: 295364160 Method Overriding C# | METHOD OVERRIDING Method Overriding in C# is similar to the virtual function in C++. Method Overriding is a technique that allows the invoking of functions from another class (base class) in the derived COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 182 class. Creating a method in the derived class with the same signature as a method in the base class is called as method overriding. In simple words, Overriding is a feature that allows a subclass or child class to provide a specific implementation of a method that is already provided by one of its super-classes or parent classes. When a method in a subclass has the same name, same parameters or signature and same return Page | 183 type(or sub-type) as a method in its super-class, then the method in the subclass is said to override the method in the super-class. Method overriding is one of the ways by which C# achieve Run Time Polymorphism(Dynamic Polymorphism). The method that is overridden by an override declaration is called the overridden base method. An override method is a new implementation of a member that is inherited from a base class. The overridden base method must be virtual, abstract, or override. Example: class base_class { public void gfg(); } class derived_class : base_class { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) public void gfg(); } class Main_Method { static void Main() { derived_class d = new derived_class(); d.gfg(); } } Here the base class is inherited in the derived class and the method gfg() which has the same signature in both the classes, is overridden. IN C# WE CAN USE 3 TYPES OF KEYWORDS FOR METHOD OVERRIDING: • virtual keyword: This modifier or keyword use within base class method. It is used to modify a method in base class for overridden that particular method in the derived class. • override: This modifier or keyword use with derived class method. It is used to modify a virtual or abstract method into derived class which presents in base class. class base_class { public virtual void gfg(); } class derived_class : base_class { public override void gfg(); } class Main_Method { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 184 static void Main() { derived d_class = new derived_class(); d.gfg(); base_class b = new derived_class(); b.gfg(); } } Here first, d refers to the object of the class derived_class and it invokes gfg() of the class derived_class then, b refers to the reference of the class base and it hold the object of class derived and it invokes gfg() of the class derived. Here gfg() method takes permission from base class to overriding the method in derived class. Example 1: Method Overriding without using virtual and override modifiers • C# // C# program to demonstrate the method overriding // without using 'virtual' and 'override' modifiers using System; // base class name 'baseClass' class baseClass { public void show() { Console.WriteLine("Base class"); } } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 185 // derived class name 'derived' // 'baseClass' inherit here class derived : baseClass { // overriding new public void show() { Console.WriteLine("Derived class"); } } class GFG { // Main Method public static void Main() { // 'obj' is the object of // class 'baseClass' baseClass obj = new baseClass(); // invokes the method 'show()' // of class 'baseClass' obj.show(); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 186 obj = new derived(); // it also invokes the method // 'show()' of class 'baseClass' obj.show(); } } Output: Base class Base class Explanation: In this program, the object obj invokes class baseClass two times and call the method show() of class baseClass. To avoid this problem we use virtual and override keyword. Example 2: Method overriding using virtual and override modifiers. • C# // C# program to illustrate the use of //'virtual' and 'override' modifiers using System; class baseClass { // show() is 'virtual' here public virtual void show() { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 187 Console.WriteLine("Base class"); } } Page | 188 // class 'baseClass' inherit // class 'derived' class derived : baseClass { //'show()' is 'override' here public override void show() { Console.WriteLine("Derived class"); } } class GFG { // Main Method public static void Main() { baseClass obj; // 'obj' is the object // of class 'baseClass' COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) obj = new baseClass(); // it invokes 'show()' // of class 'baseClass' obj.show(); // the same object 'obj' is now // the object of class 'derived' obj = new derived(); // it invokes 'show()' of class 'derived' // 'show()' of class 'derived' is overridden // for 'override' modifier obj.show(); } } Output: Base class Derived class • base Keyword: This is used to access members of the base class from derived class. It basically used to access constructors and methods or functions of the base class. The base keyword cannot use within a static method. Base keyword specifies which constructor of the base class should be invoked while creating the instances of the derived class. USE OF BASE KEYWORD: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 189 • Call methods or functions of base class from derived class. • Call constructor internally of base class at the time of inheritance. Example 1: • C# // C# program to show the use of 'base' // keyword in method overriding using System; // base class public class web { string name = "GeeksForGeeks"; // 'showdata()' is member method, // declare as virtual public virtual void showdata() { Console.WriteLine("Website Name: " + name); } } // derived class // class 'web' is inherits // class 'stream' class stream : web { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 190 string s = "Computer Science"; //'showdata()' is overridden // in derived class public override void showdata() { // Calling 'showdata()' of base // class using 'base' keyword base.showdata(); Console.WriteLine("About: " + s); } } class GFG { // Main Method static void Main() { // 'E' is object of class stream // also works as object of // class 'web' stream E = new stream(); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 191 // it first invokes 'showdata()' // of class 'web' then it invokes // 'showdata()' of class 'stream' E.showdata(); } } Output: Website Name: GeeksForGeeks About: Computer Science Example 2: How base keyword specifies the calling of base-class constructor from derived class when derived class instances are created. • C# // C# program to show how base keyword // specifies the calling of base-class // constructor from the derived class // when derived class instances are created using System; // base class public class clssA { int n1, n2; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 192 // default constructor public clssA() { Console.WriteLine("Default Constructor Invoked"); } // parameterized constructor public clssA(int i, int j) { // construct values n1 = i; n2 = j; Console.WriteLine("Parameterized Constructor Invoked"); n2); Console.WriteLine("Invoked Values are: " + n1 + " and " + } } // derived class public class DerivedClass : clssA { // This constructor will instantiate // 'clssA()' [no argument constructor] // using 'base' keyword public DerivedClass() : base() { } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 193 // This constructor will instantiate // 'clssA(int i, int j)' [parameterized // constructor] using 'base' keyword public DerivedClass(int i, int j) : base(i, j) { } // Main Method static void Main() { // invoke no argumanet constructor DerivedClass d1 = new DerivedClass(); Console.WriteLine(); // invoke parameterized constructor DerivedClass d2 = new DerivedClass(10, 20); } } Output: Default Constructor Invoked Parameterized Constructor Invoked Invoked Values are: 10 and 20 COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 194 Example 3: It shows how base keyword specifies the base-class constructor called from derived class and also calling of a method using the base keyword from the derived class. • C# // C# program to show how 'base' keyword specifies // the base-class constructor that called from // derived class and also calling a method 'swap' // from derived class using base keyword using System; // base class public class clssA { public int n1, n2; // default constructor public clssA() { Console.WriteLine("In clssA 'no argument constructor' invoked"); } // parameterized constructor public clssA(int i, int j) { // construct values n1 = i; n2 = j; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 195 Console.WriteLine("in clssA 'parameterized constructor' invoked"); n2); Console.WriteLine("the invoked values are " + n1 + " and " + Console.WriteLine(); } public virtual void swap() { Console.WriteLine("swap function of base class(clssA) invoked"); Console.WriteLine("Before swap num1 = {0} and num2 = {1}", n1, n2); // swapping int t = n1; n1 = n2; n2 = t; Console.WriteLine("After swap num1 = {0} and num2 = {1}", n1, n2); } } // derived class public class DerivedClass : clssA { // This constructor will instantiate // 'clssA' [no argument constructor] // using 'base' keyword COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 196 public DerivedClass() : base() { } // This constructor will instantiate // 'clssA' [parameterized constructor] // using 'base' keyword public DerivedClass(int i, int j) : base(i, j) { } public override void swap() { // it access the swap function of // 'clssA' using 'base' keyword base.swap(); Console.WriteLine(); Console.WriteLine("Swap function of derived class invoked"); Console.WriteLine("Before swap num1 = {0} and num2 = {1}", n1, n2); // swapping int t = n1; n1 = n2; n2 = t; Console.WriteLine("After swap num1 = {0} and num2 = {1}", n1, n2); } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 197 // Main Method static void Main() { Page | 198 // invoke no argumanet constructor DerivedClass d1 = new DerivedClass(); Console.WriteLine(); // invoke parameterized constructor DerivedClass d2 = new DerivedClass(10, 20); // calling swap function d2.swap(); } } Output: In clssA 'no argument constructor' invoked in clssA 'parameterized constructor' invoked the invoked values are 10 and 20 swap function of base class(clssA) invoked Before swap num1 = 10 and num2 = 20 After swap num1 = 20 and num2 = 10 COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Swap function of derived class invoked Before swap num1 = 20 and num2 = 10 After swap num1 = 10 and num2 = 20 Note: Page | 199 • Method overriding is possible only in derived classes. Because a method is overridden in the derived class from the base class. • A non-virtual or a static method can’t be overridden. • Both the override method and the virtual method must have the same access level modifier. Anonymous method in C# ANONYMOUS METHOD IN C# An anonymous method is a method which doesn’t contain any name which is introduced in C# 2.0. It is useful when the user wants to create an inline method and also wants to pass parameter in the anonymous method like other methods. An Anonymous method is defined using the delegate keyword and the user can assign this method to a variable of the delegate type. Syntax: delegate(parameter_list){ // Code.. }; Example : // C# program to illustrate how to // create an anonymous function using System; class GFG { public delegate void petanim(string pet); // Main method COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) static public void Main() { // An anonymous method with one parameter petanim p = delegate(string mypet) { Console.WriteLine("My favorite pet is: {0}", mypet); }; p("Dog"); } } Output: My favorite pet is: Dog IMPORTANT POINTS: • This method is also known as inline delegate. • Using this method you can create a delegate object without writing separate methods. • This method can access variable present in the outer method. Such type of variables is known as Outer variables. As shown in the below example fav is the outer variable. Example: // C# program to illustrate how an // anonymous function access variable // defined in outer method using System; class GFG { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 200 // Create a delegate public delegate void petanim(string pet); // Main method static public void Main() { string fav = "Rabbit"; // Anonymous method with one parameter petanim p = delegate(string mypet) { Console.WriteLine("My favorite pet is {0}.", mypet); // Accessing variable defined // outside the anonymous function Console.WriteLine("And I like {0} also.", fav); }; p("Dog"); } } Output: My favorite pet is Dog. And I like Rabbit also. • You can pass this method to another method which accepts delegate as a parameter. As shown in the below example: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 201 Example : // C# program to illustrate how an // anonymous method passed as a parameter using System; public delegate void Show(string x); class GFG { // identity method with two parameters public static void identity(Show mypet, string color) { color = " Black" + color; mypet(color); } // Main method static public void Main() { // Here anonymous method pass as // a parameter in identity method identity(delegate(string color) { Console.WriteLine("The color"+ " of my dog is {0}", color); }, "White"); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 202 } } Output: The color of my dog is BlackWhite • In anonymous methods, you are allowed to remove parameter-list, which means you can convert an anonymous method into a delegate. • The anonymous-method-block means the scope of the parameters in the anonymous method. • An anonymous method does not contain jump statements like goto, break, or continue. • An anonymous method does not access unsafe code. • An anonymous method does not access in, ref, and out parameter of the outer scope. • You can not use an anonymous method to the left side of the is operator. • You can also use an anonymous method as an event handler. Example: // C# program to illustrate how an // anonymous method use as a // event handler MyButton.Click += delegate(Object obj, EventArgs ev) { System.Windows.Forms.MessageBox.Show("Complete without error...!!"); } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 203 UNIT 2 UNDERSTANDING DESKTOP APPLICATIONS Human computer interaction HUMAN COMPUTER INTERACTION HCI (human-computer interaction) is the study of how people interact with computers and to what extent computers are or are not developed for successful interaction with human beings. As its name implies, HCI consists of three parts: the user, the computer itself, and the ways they work together. User By "user", we may mean an individual user, a group of users working together. An appreciation of the way people's sensory systems (sight, hearing, touch) relay information is vital. Also, different users form different conceptions or mental models about their interactions and have different ways of learning and keeping knowledge and. In addition, cultural and national differences play a part. Computer When we talk about the computer, we're referring to any technology ranging from desktop computers, to large scale computer systems. For example, if we were discussing the design of a Website, then the Website itself would be referred to as "the computer". Devices such as mobile phones or VCRs can also be considered to be “computers”. Interaction There are obvious differences between humans and machines. In spite of these, HCI attempts to ensure that they both get on with each other and interact successfully. In order to achieve a usable system, you need to apply what you know about humans and computers, and consult with likely users throughout the design process. In real systems, the schedule and the budget are important, and it is vital to find a balance between what would be ideal for the users and what is feasible in reality. The Meteoric Rise of HCI HCI surfaced in the 1980s with the advent of personal computing, just as machines such as the Apple Macintosh, IBM PC 5150 and Commodore 64 started turning up in homes and offices in society-changing numbers. For the first time, sophisticated electronic systems were available to general consumers for uses such as word processors, games units and accounting aids. Consequently, as computers were no longer room-sized, expensive tools exclusively built for experts in specialized environments, the need to create human-computer interaction that was also easy and efficient for less experienced users became increasingly vital. From its origins, HCI would expand to incorporate multiple disciplines, such as computer science, cognitive science and human-factors engineering. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 204 HCI soon became the subject of intense academic investigation. Those who studied and worked in HCI saw it as a crucial instrument to popularize the idea that the interaction between a computer and the user should resemble a human-to-human, open-ended dialogue. Initially, HCI researchers focused on improving the usability of desktop computers (i.e., practitioners concentrated on how easy computers are to learn and use). However, with the rise of technologies such as the Internet and the smartphone, computer use would increasingly move away from the desktop to embrace the mobile world. Also, HCI has steadily encompassed more fields: “…it no longer makes sense to regard HCI as a specialty of computer science; HCI has grown to be broader, larger and much more diverse than computer science itself. HCI expanded from its initial focus on individual and generic user behavior to include social and organizational computing, accessibility for the elderly, the cognitively and physically impaired, and for all people, and for the widest possible spectrum of human experiences and activities. It expanded from desktop office applications to include games, learning and education, commerce, health and medical applications, emergency planning and response, and systems to support collaboration and community. It expanded from early graphical user interfaces to include myriad interaction techniques and devices, multi-modal interactions, tool support for model-based user interface specification, and a host of emerging ubiquitous, handheld and context-aware interactions.” — John M. Carroll, author and a founder of the field of human-computer interaction. The UX Value of HCI and Its Related Realms HCI is a broad field which overlaps with areas such as user-centered design (UCD), user interface (UI) design and user experience (UX) design. In many ways, HCI was the forerunner to UX design. Despite that, some differences remain between HCI and UX design. Practitioners of HCI tend to be more academically focused. They're involved in scientific research and developing empirical understandings of users. Conversely, UX designers are almost invariably industry-focused and involved in building products or services—e.g., smartphone apps and websites. Regardless of COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 205 this divide, the practical considerations for products that we as UX professionals concern ourselves with have direct links to the findings of HCI specialists about users’ mindsets. With the broader span of topics that HCI covers, UX designers have a wealth of resources to draw from, although much research remains suited to academic audiences. Those of us who are designers also lack the luxury of time which HCI specialists typically enjoy. So, we must stretch beyond our industry-dictated constraints to access these more academic findings. When you do that well, Page | 206 you can leverage key insights into achieving the best designs for your users. By “collaborating” in this way with the HCI world, designers can drive impactful changes in the market and society. THE GOALS OF HCI The goals of HCI are to produce usable and safe systems, as well as functional systems. In order to produce computer systems with good usability, developers must attempt to: • Understand the factors that determine how people use technology • Develop tools and techniques to enable building suitable systems • Achieve efficient, effective, and safe interaction • Put people first Underlying the whole theme of HCI is the belief that people using a computer system should come first. Their needs, capabilities and preferences for conducting various tasks should direct developers in the way that they design systems. People should not have to change the way that they use a system in order to fit in with it. Instead, the system should be designed to match their requirements. USABILITY Usability is one of the key concepts in HCI. It is concerned with making systems easy to learn and use. A usable system is: • Easy to learn • Easy to remember how to use • Effective to use • Efficient to use • Safe to use • Enjoyable to use WHY IS USABILITY IMPORTANT? Many everyday systems and products seem to be designed with little regard to usability. This leads to frustration, wasted time and errors. This list contains examples of interactive products: mobile phone, computer, personal organizer, remote control, soft drink machine, coffee machine, COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) ATM, ticket machine, library information system, the web, photocopier, watch, printer, stereo, calculator, videogame etc¦. How many are actually easy, effortless, and enjoyable to use? For example, a photocopier might have buttons like these on its control panel. C Imagine that you just put your document into the photocopier and set the photocopier to make 15 copies, sorted and stapled. Then you push the big button with the "C" to start making your copies. What do you think will happen? (a) The photocopier makes the copies correctly. (b) The photocopier settings are cleared and no copies are made. If you selected (b) you are right! The "C" stands for clear, not copy. The copy button is actually the button on the left with the "line in a diamond" symbol. This symbol is widely used on photocopiers, but is of little help to someone who is unfamiliar with this. FACTORS IN HCI There are a large number of factors which should be considered in the analysis and design of a system using HCI principles. Many of these factors interact with each other, making the analysis even more complex. The main factors are listed in the table below: Organisation Factors Training, job design, politics, roles, workorganisation Environmental Factors Noise, heating, lighting, ventilation Health and Safety Factors The User Cognitive processes and capabilities Motivation, enjoyment, satisfaction, personality, experience Comfort Factors Seating, equipment, layout. User Interface Input devices, output devices, dialogue structures, use of colour, icons, commands, navigation, graphics, natural language, user support, multimedia, Task Factors Easy, complex, novel, task allocation, monitoring, skills Constraints Cost, timescales, budgets, staff, equipment, buildings System Functionality Hardware, software, application Productivity Factors Increase output, increase quality, decrease costs, decrease errors, increase innovation COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 207 DISCIPLINES CONTRIBUTING TO HCI The field of HCI covers a wide range of topics, and its development has relied on contributions from many disciplines. Some of the main disciplines which have contributed to HCI are: Computer Science • Technology • software design, development & maintenance • User Interface Management Systems (UIMS) & User Interface Development Environments (UIDE) • prototyping tools • graphics Cognitive Psychology • Information processing • Capabilities • Limitations • Cooperative working • Performance prediction Social Psychology • Social & organizational structures Ergonomics/Human Factors • Hardware design • Display readability Linguistics • Natural language interfaces Artificial Intelligence • Intelligent software Philosophy, Sociology & Anthropology • Computer supported cooperative work (CSCW) Engineering & Design COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 208 • Graphic design • Engineering principles Windows, forms, applications WINDOWS, FORMS, APPLICATIONS Windows Forms is a Graphical User Interface(GUI) class library which is bundled in .Net Framework. Its main purpose is to provide an easier interface to develop the applications for desktop, tablet, PCs. It is also termed as the WinForms. The applications which are developed by using Windows Forms or WinForms are known as the Windows Forms Applications that runs on the desktop computer. WinForms can be used only to develop the Windows Forms Applications not web applications. WinForms applications can contain the different type of controls like labels, list boxes, tooltip etc. Below is an example of a simple Windows form application C#. It shows a simple Login screen, which is accessible by the user. The user will enter the required credentials and then will click the Login button to proceed. So an example of the controls available in the above application 1. This is a collection of label controls which are normally used to describe adjacent controls. So in our case, we have 2 textboxes, and the labels are used to tell the user that one textbox is for entering the user name and the other for the password. 2. The 2 textboxes are used to hold the username and password which will be entered by the user. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 209 3. Finally, we have the button control. The button control will normally have some code attached to perform a certain set of actions. So for example in the above case, we could have the button perform an action of validating the user name and password which is entered by the user. Designing a windows form DESIGNING A WINDOWS FORM C# HELLO WORLD IN WINDOWS FORM Now let’s look at an example of how we can implement a simple ‘hello world’ application in Visual Studio. For this, we would need to implement the below-mentioned steps Step 1) The first step involves the creation of a new project in Visual Studio. After launching Visual Studio, you need to choose the menu option New->Project. Step 2) The next step is to choose the project type as a Windows Forms application. Here we also need to mention the name and location of our project. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 210 Page | 211 1. In the project dialog box, we can see various options for creating different types of projects in Visual Studio. Click the Windows option on the left-hand side. 2. When we click the Windows options in the previous step, we will be able to see an option for Windows Forms Application. Click this option. 3. We will give a name for the application. In our case, it is DemoApplication. We will also provide a location to store our application. 4. Finally, we click the ‘OK’ button to let Visual Studio create our project. If the above steps are followed, you will get the below output in Visual Studio. Output:- COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 212 You will see a Form Designer displayed in Visual Studio. It’s in this Form Designer that you will start building your Windows Forms application. In the Solution Explorer, you will also be able to see the DemoApplication Solution. This solution will contain the below 2 project files COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) 1. A Form application called Forms1.cs. This file will contain all of the code for the Windows Form application. 2. The Main program called Program.cs is default code file which is created when a new application is created in Visual Studio. This code will contain the startup code for the application as a whole. On the left-hand side of Visual Studio, you will also see a ToolBox. The toolbox contains all the controls which can be added to a Windows Forms. Controls like a text box or a label are just some of the controls which can be added to a Windows Forms. Below is a screenshot of how the Toolbox looks like. Step 3) In this step, we will now add a label to the Form which will display “Hello World.” From the toolbox, you will need to choose the Label control and simply drag it onto the Form. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 213 Page | 214 Once you drag the label to the form, you can see the label embedded on the form as shown below. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Step 4) The next step is to go to the properties of the control and Change the text to ‘Hello World’. To go to the properties of a control, you need to right-click the control and choose the Properties menu option Page | 215 • The properties panel also shows up in Visual Studio. So for the label control, in the properties control, go to the Text section and enter “Hello World”. • Each Control has a set of properties which describe the control. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 216 If you follow all of the above steps and run your program in Visual Studio, you will get the following output Output:- In the output, you can see that the Windows Form is displayed. You can also see ‘Hello World’ is displayed on the form. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) ADDING CONTROLS TO A FORM We had already seen how to add a control to a form when we added the label control in the earlier section to display “Hello World.” Let’s look at the other controls available for Windows forms and see some of their common properties. In our Windows form application in C# examples, we will create one form which will have the following functionality. 1. The ability for the user to enter name and address. 2. An option to choose the city in which the user resides in 3. The ability for the user to enter an option for the gender. 4. An option to choose a course which the user wants to learn. There will make choices for both C# and ASP.Net So let’s look at each control in detail and add them to build the form with the above-mentioned functionality. Group Box A group box is used for logical grouping controls into a section. Let’s take an example if you had a collection of controls for entering details such as name and address of a person. Ideally, these are details of a person, so you would want to have these details in a separate section on the Form. For this purpose, you can have a group box. Let’s see how we can implement this with an example shown below Step 1) The first step is to drag the Groupbox control onto the Windows Form from the toolbox as shown below COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 217 Page | 218 Step 2) Once the groupbox has been added, go to the properties window by clicking on the groupbox control. In the properties window, go to the Text property and change it to “User Details”. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 219 Once you make the above changes, you will see the following output Output:- In the output, you can clearly see that the Groupbox was added to the form. You can also see that the text of the groupbox was changed to “User Details.” COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Label Control Next comes the Label Control. The label control is used to display a text or a message to the user on the form. The label control is normally used along with other controls. Common examples are wherein a label is added along with the textbox control. The label indicates to the user on what is expected to fill up in the textbox. Let’s see how we can Page | 220 implement this with an example shown below. We will add 2 labels, one which will be called ‘name’ and the other called ‘address.’ They will be used in conjunction with the textbox controls which will be added in the later section. Step 1) The first step is to drag the label control on to the Windows Form from the toolbox as shown below. Make sure you drag the label control 2 times so that you can have one for the ‘name’ and the other for the ‘address’. Step 2) Once the label has been added, go to the properties window by clicking on the label control. In the properties window, go to the Text property of each label control. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 221 Once you make the above changes, you will see the following output Output:- You can see the label controls added to the form. Textbox COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) A textbox is used for allowing a user to enter some text on the Windows application in C#. Let’s see how we can implement this with an example shown below. We will add 2 textboxes to the form, one for the Name and the other for the address to be entered for the user Step 1) The first step is to drag the textbox control onto the Windows Form from the toolbox as shown below Step 2) Once the text boxes have been added, go to the properties window by clicking on the textbox control. In the properties window, go to the Name property and add a meaningful name to each textbox. For example, name the textbox for the user as txtName and that for the address as txtAddress. A naming convention and standard should be made for controls because it becomes easier to add extra functionality to these controls, which we will see later on. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 222 Page | 223 Once you make the above changes, you will see the following output Output:- COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) In the output, you can clearly see that the Textboxes was added to the form. List box A Listbox is used to showcase a list of items on the Windows form. Let’s see how we can implement this with an example shown below. We will add a list box to the form to store some city locations. Step 1) The first step is to drag the list box control onto the Windows Form from the toolbox as shown below Step 2) Once the list box has been added, go to the properties window by clicking on the list box control. 1. First, change the property of the Listbox box control, in our case, we have changed this to lstCity 2. Click on the Items property. This will allow you to add different items which can show up in the list box. In our case, we have selected items “collection”. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 224 3. In the String Collection Editor, which pops up, enter the city names. In our case, we have entered “Mumbai”, “Bangalore” and “Hyderabad”. 4. Finally, click on the ‘OK’ button. Once you make the above changes, you will see the following output Output:- In the output, you can see that the Listbox was added to the form. You can also see that the list box has been populated with the city values. RadioButton A Radiobutton is used to showcase a list of items out of which the user can choose one. Let’s see how we can implement this with an example shown below. We will add a radio button for a male/female option. Step 1) The first step is to drag the ‘radiobutton’ control onto the Windows Form from the toolbox as shown below. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 225 Page | 226 Step 2) Once the Radiobutton has been added, go to the properties window by clicking on the Radiobutton control. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) 1. First, you need to change the text property of both Radio controls. Go the properties windows and change the text to a male of one radiobutton and the text of the other to female. 2. Similarly, change the name property of both Radio controls. Go the properties windows and change the name to ‘rdMale’ of one radiobutton and to ‘rdfemale’ for the other one. One you make the above changes, you will see the following output Output:- You will see the Radio buttons added to the Windows form. Checkbox A checkbox is used to provide a list of options in which the user can choose multiple choices. Let’s see how we can implement this with an example shown below. We will add 2 checkboxes to our Windows forms. These checkboxes will provide an option to the user on whether they want to learn C# or ASP.Net. Step 1) The first step is to drag the checkbox control onto the Windows Form from the toolbox as shown below COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 227 Page | 228 Step 2) Once the checkbox has been added, go to the properties window by clicking on the Checkbox control. In the properties window, 1. First, you need to change the text property of both checkbox controls. Go the properties windows and change the text to C# and ASP.Net. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) 2. Similarly, change the name property of both Radio controls. Go the properties windows and change the name to chkC of one checkbox and to chkASP for the other one. Once you make the above changes, you will see the following output Output:- Button A button is used to allow the user to click on a button which would then start the processing of the form. Let’s see how we can implement this with an example shown below. We will add a simple button called ‘Submit’ which will be used to submit all the information on the form. Step 1) The first step is to drag the button control onto the Windows Form from the toolbox as shown below Step 2) Once the Button has been added, go to the properties window by clicking on the Button control. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 229 Page | 230 1. First, you need to change the text property of the button control. Go the properties windows and change the text to ‘submit’. 2. Similarly, change the name property of the control. Go the properties windows and change the name to ‘btnSubmit’. Once you make the above changes, you will see the following output Output:- COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 231 Congrats, you now have your first basic Windows Form in place. Let’s now go to the next topic to see how we can do Event handling for Controls. C# EVENT HANDLING FOR CONTROLS When working with windows form, you can add events to controls. An event is something that happens when an action is performed. Probably the most common action is the clicking of a button on a form. In C# Windows Forms, you can add code which can be used to perform certain actions when a button is pressed on the form. Normally when a button is pressed on a form, it means that some processing should take place. Let’s take a look at one of the event and how it can be handled before we go to the button event scenario. The below example will showcase an event for the Listbox control. So whenever an item is selected in the listbox control, a message box should pop up which shows the item selected. Let’s perform the following steps to achieve this. Step 1) Double click on the Listbox in the form designer. By doing this, Visual Studio will automatically open up the code file for the form. And it will automatically add an event method to the code. This event method will be triggered, whenever any item in the listbox is selected. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 232 Above is the snippet of code which is automatically added by Visual Studio, when you doubleclick the List box control on the form. Now let’s add the below section of code to this snippet of code, to add the required functionality to the listbox event. 1. This is the event handler method which is automatically created by Visual Studio when you double-click the List box control. You don’t need to worry about the complexity of the method name or the parameters passed to the method. 2. Here we are getting the SelectedItem through the lstCity.SelectedItem property. Remember that lstCity is the name of our Listbox control. We then use the GetItemText method to get the actual value of the selected item. We then assign this value to the text variable. 3. Finally, we use the MessageBox method to display the text variable value to the user. One you make the above changes, and run the program in Visual Studio you will see the following output Output:- COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 233 From the output, you can see that when any item from the list box is selected, a message box will pops up. This will show the selected item from the listbox. Now let’s look at the final control which is the button click Method. Again this follows the same philosophy. Just double click the button in the Forms Designer and it will automatically add the method for the button event handler. Then you just need to add the below code. 1. This is the event handler method which is automatically created by Visual Studio when you double click the button control. You don’t need to worry on the complexity of the method name or the parameters passed to the method. 2. Here we are getting values entered in the name and address textbox. The values can be taken from the text property of the textbox. We then assign the values to 2 variables, name, and address accordingly. 3. Finally, we use the MessageBox method to display the name and address values to the user. One you make the above changes, and run the program in Visual Studio you will see the following output COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Output:- Page | 234 1. First, enter a value in the name and address field. 2. Then click on the Submit button Once you click the Submit button, a message box will pop, and it will correctly show you what you entered in the user details section. Tree and PictureBox Control There are 2 further controls we can look at, one is the ‘Tree Control’ and the other is the ‘Image control’. Let’s look at examples of how we can implement these controls Tree Control – The tree control is used to list down items in a tree like fashion. Probably the best example is when we see the Windows Explorer itself. The folder structure in Windows Explorer is like a tree-like structure. Let’s see how we can implement this with an example shown below. Step 1) The first step is to drag the Tree control onto the Windows Form from the toolbox as shown below COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 235 Step 2) The next step is to start adding nodes to the tree collection so that it can come up in the tree accordingly. First, let’s follow the below sub-steps to add a root node to the tree collection. 1. Go to the properties toolbox for the tree view control. Click on the Node’s property. This will bring up the TreeNode Editor 2. In the TreeNode Editor click on the Add Root button to add a root node to the tree collection. 3. Next, change the text of the Root node and provide the text as Root and click ‘OK’ button. This will add Root node. Step 3) The next step is to start adding the child nodes to the tree collection. Let’s follow the below sub-steps to add child root node to the tree collection. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 236 1. First, click on the Add child button. This will allow you to add child nodes to the Tree collection. 2. For each child node, change the text property. Keep on repeating the previous step and this step and add 2 additional nodes. In the end, you will have 3 nodes as shown above, with the text as Label, Button, and Checkbox respectively. 3. Click on the OK button Once you have made the above changes, you will see the following output. Output:- You will be able to see the Tree view added to the form. When you run the Windows form application, you can expand the root node and see the child nodes in the list. PictureBox Control COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) This control is used to add images to the Winforms C#. Let’s see how we can implement this with an example shown below. Step 1) The first step is to drag the PictureBox control onto the C# Windows Form from the toolbox as shown below Page | 237 Step 2) The next step is to actually attach an image to the picture box control. This can be done by following the below steps. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) 1. First, click on the Image property for the PictureBox control. A new window will pops out. 2. In this window, click on the Import button. This will be used to attach an image to the picturebox control. 3. A dialog box will pop up in which you will be able to choose the image to attach the picturebox 4. Click on the OK button One you make the above changes, you will see the following output Output:- From the output, you can see that an image is displayed on the form. Summary • A Windows form in C# application is one that runs on the desktop of a computer. Visual Studio Form along with C# can be used to create a Windows Forms application. • Controls can be added to the Windows forms C# via the Toolbox in Visual Studio. Controls such as labels, checkboxes, radio buttons, etc. can be added to the form via the toolbox. • One can also use advanced controls like the tree view control and the PictureBox control. • Event handlers are used to respond to events generated from controls. The most common one is the one added for the button clicked event. Windows form event model WINDOWS FORM EVENT MODEL The Desktop Guide documentation for .NET 5 (and .NET Core) is under construction. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 238 Event-driven applications execute code in response to an event. Each form and control exposes a predefined set of events that you can program against. If one of these events occurs and there's code an associated event handler, that code is invoked. The types of events raised by an object vary, but many types are common to most controls. For example, most objects will handle a Click event. If a user clicks a form, code in the form's Click event handler is executed. Note Many events occur in conjunction with other events. For example, in the course of the DoubleClick event occurring, the MouseDown, MouseUp, and Click events occur. For information about how to raise and consume an event, see Handling and raising events. Delegates and their role Delegates are classes commonly used within .NET to build event-handling mechanisms. Delegates roughly equate to function pointers, commonly used in Visual C++ and other objectoriented languages. Unlike function pointers however, delegates are object-oriented, type-safe, and secure. Also, where a function pointer contains only a reference to a particular function, a delegate consists of a reference to an object, and references to one or more methods within the object. This event model uses delegates to bind events to the methods that are used to handle them. The delegate enables other classes to register for event notification by specifying a handler method. When the event occurs, the delegate calls the bound method. For more information about how to define delegates, see Handling and raising events. Delegates can be bound to a single method or to multiple methods, referred to as multicasting. When creating a delegate for an event, you typically create a multicast event. A rare exception might be an event that results in a specific procedure (such as displaying a dialog box) that wouldn't logically repeat multiple times per event. For information about how to create a multicast delegate, see How to combine delegates (Multicast Delegates). A multicast delegate maintains an invocation list of the methods it's bound to. The multicast delegate supports a Combine method to add a method to the invocation list and a Remove method to remove it. When an event is recorded by the application, the control raises the event by invoking the delegate for that event. The delegate in turn calls the bound method. In the most common case (a multicast delegate), the delegate calls each bound method in the invocation list in turn, which provides a one-to-many notification. This strategy means that the control doesn't need to maintain a list of target objects for event notification—the delegate handles all registration and notification. Delegates also enable multiple events to be bound to the same method, allowing a many-to-one notification. For example, a button-click event and a menu-command–click event can both COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 239 invoke the same delegate, which then calls a single method to handle these separate events the same way. The binding mechanism used with delegates is dynamic: a delegate can be bound at run-time to any method whose signature matches that of the event handler. With this feature, you can set up or change the bound method depending on a condition and to dynamically attach an event handler to a control. The order in which events are raised in Windows Forms applications is of particular interest to developers concerned with handling each of these events in turn. When a situation calls for meticulous handling of events, such as when you are redrawing parts of the form, an awareness of the precise order in which events are raised at run time is necessary. This topic provides some details on the order of events during several important stages in the lifetime of applications and controls. For specific details about the order of mouse input events, see Mouse Events in Windows Forms. For an overview of events in Windows Forms, see Events Overview. For details about the makeup of event handlers, see Event Handlers Overview. Application Startup and Shutdown Events The Form and Control classes expose a set of events related to application startup and shutdown. When a Windows Forms application starts, the startup events of the main form are raised in the following order: • Control.HandleCreated • Control.BindingContextChanged • Form.Load • Control.VisibleChanged • Form.Activated • Form.Shown When an application closes, the shutdown events of the main form are raised in the following order: • Form.Closing • Form.FormClosing • Form.Closed • Form.FormClosed • Form.Deactivate The ApplicationExit event of the Application class is raised after the shutdown events of the main form. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 240 Note Visual Basic 2005 includes additional application events, such as WindowsFormsApplicationBase.Startup and WindowsFormsApplicationBase.Shutdown. Focus and Validation Events When you change the focus by using the keyboard (TAB, SHIFT+TAB, and so on), by calling the Select or SelectNextControl methods, or by setting the ActiveControl property to the current form, focus events of the Control class occur in the following order: • Enter • GotFocus • Leave • Validating • Validated • LostFocus When you change the focus by using the mouse or by calling the Focus method, focus events of the Control class occur in the following order: • Enter • GotFocus • LostFocus • Leave • Validating • Validated WINDOWS FORMS EVENTS LIFECYCLE Today there are a large number of books covering .NET and Windows Forms. While most of these books discuss the essentials of working with Windows Forms and guide you well on your way to becoming proficient in developing Windows Forms applications, very few books cover a vital and much needed topic. And this topic is: the sequence of events that are triggered for a Form. Knowing the lifecycle of a Form can help you place important bits of code in relevant events. If you look at ASP.NET tutorials and books, you will find many references to the Web Page lifecyle but what about Windows Forms lifecycle? Sadly, there's not much concrete information about this. The aim of this article is, therefore, to delve into this topic and provide insightful knowledge about Form events. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 241 The events in the lifecycle of a Form from the time it is launched to the time it is closed are listed below: • Move: This event occurs when the form is moved. Although by default, when a form is instantiated and launched, the user does not move it, yet this event is triggered before the Load event occurs. • Load: This event occurs before a form is displayed for the first time. • Visible Changed: This event occurs when the Visible property value changes. • Activated: This event occurs when the form is activated in code or by the user. • Shown: This event occurs whenever the form is first displayed. • Paint: This event occurs when the control is redrawn. • Deactivate: This event occurs when the form loses focus and is not the active form. • Closing: This event occurs when the form is closing. • Closed: This event occurs when the form is being closed. Let us view this through an example. 1. First, launch Visual Studio IDE (2005 or 2008) and create a Windows Forms application. Figure 1: New Project Dialog Box 2. Give a suitable name and click OK. This will create the application and open it in Design view. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 242 Page | 243 Figure 2: Application in the Design view 3. Open the Form properties window. The easiest way to do this is: select the Form in the design view and press the F4 key. 4. Click the Events tab and select the Move event. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 244 Figure 3: Form events 5. Double click on it. This will cause the event handler to be auto-generated in the Code View. 6. Switch back to the Design View and in the Form properties window, double click the Load event. 7. Likewise, repeat this procedure for all the events that were listed earlier. 8. Open the Code View of Form1.Designer.cs and add the code marked in bold. using System.IO; namespace LifecycleDemo { partial class Form1 COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) { StreamWriter sr = new treamWriter("D:\\formevents.txt"); /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.IContainer components = null; /// <summary> /// Clean up any resources being used. /// </summary> /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> protected override void Dispose(bool disposing) { if (disposing && (components != null)) { components.Dispose(); } base.Dispose(disposing); sr.Close(); } #region Windows Form Designer generated code #endregion } } 9. Open the Code View of Form 1 and add the code marked in bold. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 245 public partial class Form1 : Form { Page | 246 public Form1() { InitializeComponent(); } private void Form1_Move(object sender, EventArgs e) { sr.WriteLine("1 - Move event"); } private void Form1_Load(object sender, EventArgs e) { sr.WriteLine("2 - Load event"); } private void Form1_Activated(object sender, EventArgs e) { sr.WriteLine("3 - Activated event"); } private void Form1_VisibleChanged(object sender, EventArgs e) { sr.WriteLine("4 - VisibleChanged event"); } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) private void Form1_Shown(object sender, EventArgs e) { sr.WriteLine("5 -Shown event"); } private void Form1_Paint(object sender, PaintEventArgs e) { sr.WriteLine("6 - Paint event"); } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { sr.WriteLine("7 - FormClosed event"); } private void Form1_FormClosing(object sender, FormClosingEventArgs e) { sr.WriteLine("8 - FormClosing"); } private void Form1_Deactivate(object sender, EventArgs e) { sr.WriteLine("9 - Deactivate"); } } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 247 10. Next, you save, build and execute the application. (File->Save is used for the save operation and Build->Build Solution is used to build the application. To execute, click Debug>Start Debugging. Page | 248 Figure 4: Form shown during execution of the application 11. Switch to some other application, such that the form is no longer in focus. 12. Switch back to the Windows Form so that it regains focus. 13. Exit the Windows Form application. 14. Open the text file, formevents.txt. You will observe the output similar to the one shown in Figure 5. (Output may vary if you perform some other actions in between causing additional events to be raised). Figure 5: Text file contents showing event lifecycle COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) The Move, Load, VisibleChanged and Activated events are raised even before the Form is shown. Then the Shown event takes place. This is followed by the Paint event. These events are common for any application and are always standard. When you switch the focus to some other application, the Deactivate event occurs. When the form regains focus, the Activated event is raised. Then the form is painted again because it has regained focus. When you attempt to close the form, the FormClosing and FormClosed events are raised. Finally, after the form is closed, Deactivate is raised once more. If you had inserted a WriteLine for Dispose as well (which has not been written as of now) you would see that statement appearing after the Deactivate. Visual inheritance VISUAL INHERITANCE Inheritance is the single most important new object-oriented feature in Visual Studio.NET. Surprisingly, not much has been written about the subject, and most of the information available is either very basic and an "overview" at best, or just plain misleading. In this article, I give you a real-world overview of what inheritance? especially visual inheritance? can do for you. Inheritance is a key concept for a language or environment to be considered truly objectoriented, rather than just object-based. In previous versions of Visual Studio (up to version 6.0), Microsoft made inheritance available in languages such as Visual C++, Visual FoxPro and Visual J++, but not in Visual Basic. This means that the majority of Microsoft's developer community is in for a major paradigm shift. This article will help make the transition as smooth as possible for you. Unlike the descriptions in most .NET books and articles, inheritance is relatively simple. I recently read several articles that make statements like, "Free Threading and Inheritance are powerful features, but a lot of Visual Basic developers will shoot themselves in the foot applying these technologies incorrectly." While I agree with this statement for the Free Threading feature, I have to disagree with the inheritance part. Visual Basic developers who are already familiar with object-based development face a steep, but fairly short learning curve. C++ and Visual FoxPro developers moving into VB.NET or C# will be able to make this move painlessly. In this article, we will create a base data entry form class that provides some standard features. We will subclass this class to create individual data entry forms. Beyond that, we will create specialized subclasses of the subclassed data entry forms. We will create all examples in Visual Basic.NET and C#. Inheritance is a feature provided by the Common Language Runtime (CLR) and is, therefore, not language specific. As you will see, all the concepts are available in a similar fashion in both languages, although the syntax is slightly different. All our examples will have methods that would in real life normally provide a lot of functionality (such as saving information). However, COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 249 we will focus our attention on the Inheritance part of this, and will simply represent all other code with message boxes, so we can easily see what's going on in our code. Creating a Base Data Entry Form Class The basic scenario is simple: We want to create a base data entry form class that provides OK, Page | 250 Cancel and Apply buttons. Those buttons will trigger Save() and Cancel() methods. The base class itself is not designed to be used for data entry ? we will use subclasses (classes based on the base class) for that. Visual Basic developers can imagine the base form like a "template on steroids." Figure 1 shows what our base data entry form class looks like. Figure 1 Our data entry base class is rather simple. All other details will be added in subclasses. To create this class, create a new WinForms project (C# or VB.NET). This will automatically create a default form for you. You could use this form and turn it into our base form, but I used mine only as a test-bench to test our classes. To add the real class, right-click the solution in the Solution Explorer (I named my solutions CSInheritanceSample and VBInheritanceSample) and select "Add Windows Form." As the name, use "DataEntryBaseForm". Add three new buttons to the form (as shown in Figure 1) and set the names to "cmdOK", "cmdCancel" and "cmdApply". To make our form always look nice, we would like the buttons to maintain their position relative to the bottom-right edge of the form. In Visual Studio 6 languages (pretty much all of them), we would have needed to write manual resize code. In Visual Studio.NET, we can simply set the Anchor property to "BottomRight" (see Figure 2). COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 251 Figure 2 We create the base form and define the buttons to be positioned relative to the bottom right corner of the form. In addition, we add two methods to the form: Cancel() and Save(). The buttons on the form will call those methods. In this example, those methods don't do anything by default but show a message box. The idea is that we could later add code to these methods in the base class to automatically provide inherited save and cancel functionality in the subclasses. Or, we could override or augment the base class methods by adding code in the subclasses. But, I'm getting ahead of myself. Let's look at the base form class code first. Here is the C# version: namespace CSInheritanceSample { using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.WinForms; public class DataEntryBaseForm : COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) System.WinForms.Form { private System.ComponentModel.Container components; private System.WinForms.Button cmdOK; private System.WinForms.Button cmdCancel; private System.WinForms.Button cmdApply; public DataEntryBaseForm() { InitializeComponent(); } public override void Dispose() { base.Dispose(); components.Dispose(); } private void InitializeComponent() { this.components = new System.ComponentModel.Container (); this.cmdOK = new System.WinForms.Button (); this.cmdApply = new System.WinForms.Button (); this.cmdCancel = new COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 252 System.WinForms.Button (); cmdOK.Location = new System.Drawing.Point (120, 185); cmdOK.Size = new System.Drawing.Size (60, 23); cmdOK.TabIndex = 2; cmdOK.Anchor = System.WinForms.AnchorStyles.BottomRight; cmdOK.Text = "&OK"; cmdOK.Click += new System.EventHandler (this.cmdOK_Click); cmdApply.Location = new System.Drawing.Point (248, 185); cmdApply.Size = new System.Drawing.Size (60, 23); cmdApply.TabIndex = 0; cmdApply.Anchor = System.WinForms.AnchorStyles.BottomRight; cmdApply.Text = "&Apply"; cmdApply.Click += new System.EventHandler (this.cmdApply_Click); cmdCancel.Location = new System.Drawing.Point (184, 185); cmdCancel.Size = new System.Drawing.Size (60, 23); cmdCancel.TabIndex = 1; cmdCancel.Anchor = System.WinForms.AnchorStyles.BottomRight; cmdCancel.Text = "&Cancel"; cmdCancel.Click += new System.EventHandler (this.cmdCancel_Click); this.Text = "DataEntryBaseForm"; this.AutoScaleBaseSize = new COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 253 System.Drawing.Size (5, 13); this.ClientSize = new System.Drawing.Size (312, 213); this.Controls.Add (this.cmdOK); this.Controls.Add (this.cmdCancel); this.Controls.Add (this.cmdApply); } protected void cmdApply_Click (object sender, System.EventArgs e) { this.Save(); cmdApply.Enabled=false; } protected void cmdCancel_Click (object sender, System.EventArgs e) { this.Cancel(); this.Close(); } protected void cmdOK_Click (object sender, System.EventArgs e) { this.Save(); this.Close(); } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 254 public void Save() { MessageBox.Show("Base Form Save"); } public void Cancel() { MessageBox.Show("Base Form Cancel"); } } } And, here is the Visual Basic.NET version: Imports System.Drawing Imports System.WinForms Imports System.ComponentModel Public Class DataEntryBaseForm Inherits System.WinForms.Form Public Sub New() MyBase.New DataEntryBaseForm = Me 'This call is required by the ' Win Form Designer. InitializeComponent() End Sub COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 255 'Form overrides dispose to clean ' up the component list. Overrides Public Sub Dispose() MyBase.Dispose components.Dispose End Sub #Region " Windows Form Designer code " 'Required by the Windows Form Designer Private components As _ System.ComponentModel.Container Private WithEvents cmdApply As _ System.WinForms.Button Private WithEvents cmdCancel As _ System.WinForms.Button Private WithEvents cmdOK As _ System.WinForms.Button Dim WithEvents DataEntryBaseForm As _ System.WinForms.Form Private Sub InitializeComponent() Me.components = New _ System.ComponentModel.Container() Me.cmdOK = New System.WinForms.Button() Me.cmdApply = New System.WinForms.Button() Me.cmdCancel = New _ COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 256 System.WinForms.Button() cmdOK.Location = New _ System.Drawing.Point(416, 200) cmdOK.Size = New _ System.Drawing.Size(75, 23) cmdOK.TabIndex = 0 cmdOK.Text = "OK" cmdApply.Location = New _ System.Drawing.Point(248, 200) cmdApply.Size = New _ System.Drawing.Size(75, 23) cmdApply.TabIndex = 2 cmdApply.Text = "Apply" cmdCancel.Location = New _ System.Drawing.Point(328, 200) cmdCancel.Size = New _ System.Drawing.Size(75, 23) cmdCancel.TabIndex = 1 cmdCancel.Text = "Cancel" Me.Text = "DataEntryBaseForm" Me.AutoScaleBaseSize = New _ System.Drawing.Size(5, 13) Me.ClientSize = New _ System.Drawing.Size(504, 237) COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 257 Me.Controls.Add(cmdApply) Me.Controls.Add(cmdCancel) Me.Controls.Add(cmdOK) End Sub #End Region Protected Sub cmdOK_Click(ByVal sender _ As Object, ByVal e As System.EventArgs) Me.Save() Me.Close() End Sub Protected Sub cmdCancel_Click(ByVal sender _ As Object, ByVal e As System.EventArgs) Me.Cancel() Me.Close() End Sub Protected Sub cmdApply_Click(ByVal sender _ As Object, ByVal e As System.EventArgs) Me.Save() cmdApply.Enabled = False End Sub Public Sub Save() MessageBox.Show("Base Form Save") End Sub COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 258 Public Sub Cancel() MessageBox.Show("Base Form Cancel") End Sub End Class As you can see, both versions have quite a bit of code, but most of it has been created automatically. What's really important are the class definition and the methods we've added. Let's look closely at that part of the code in C#: public class DataEntryBaseForm : System.WinForms.Form { public void Save() { MessageBox.Show("Base Form Save"); } public void Cancel() { MessageBox.Show("Base Form Cancel"); } } The Visual Basic.NET syntax is different, but the overall concept is the same: Public Class DataEntryBaseForm Inherits System.WinForms.Form Public Sub Save() MessageBox.Show("Base Form Save") COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 259 End Sub Public Sub Cancel() MessageBox.Show("Base Form Cancel") End Sub End Class Here's what's happening: First of all, we create a new class named "DataEntryBaseForm". This class is subclassed from System.WinForms.Form, which is the .NET standard form class. This means that our new class will have everything a standard form has, and it will behave the same way any other form behaves. Basically, we have a class that is a form ? a specialized version of a form perhaps, because we added two methods, but still a form. If Microsoft decides that forms are to behave or look differently and changes "System.WinForms.Form", our new form will automatically behave and look the same way, because it is a form. For this reason, subclassing relationships are often called "is-a" relationships. One of the key things here is that this was easy! We didn't really do anything special, and Visual Studio.NET took care of everything for us. And even if it didn't, it wouldn't have been hard to write the same class from scratch. Inheritance is simple! You may now point out that there are quite a number of lines in the first listing of that code. That is true. But, as mentioned before, this is all code generated for us by Visual Studio.NET. The majority of the code deals with adding buttons, setting properties and adding event-handling code. Talking about event handling code, I still owe you an explanation for how the Save() and Cancel() methods are called. To add event code to a button click method, we can double-click the button, and Visual Studio.NET sets up all the required bindings. The click event of the OK button is linked to the code that reacts to the event in the following fashion (as always, the C# version first): cmdOK.Click += new System.EventHandler (this.cmdOK_Click); And, in VB.NET: Private WithEvents cmdOK As _ System.WinForms.Button COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 260 Basically, the click event points to the cmdOK_Click() method, which is a member of the current form. The system event handler is used to bind the two things together. As mentioned before, you don't really have to create this code since Visual Studio.NET does it for you, but it still doesn't hurt to know what's going on (as we will see a little further down). Here's the C# code in the cmdOK_Click() event: protected void cmdOK_Click (object sender, System.EventArgs e) { this.Save(); this.Close(); } Visual Basic.NET: Protected Sub cmdOK_Click(ByVal sender As _ Object, ByVal e As System.EventArgs) Me.Save() Me.Close() End Sub The code is really trivial. First, the save method is called, then the form is closed. (You might argue that we should check whether we saved successfully, but this isn't really relevant at the moment, as we are trying to understand the concepts of inheritance.) Visual FoxPro people might be slightly confused at this point, since we can talk to the Save() method using the "this/Me" pointer (which, by the way, is optional in Visual Studio.NET) rather than using the equivalent to Visual FoxPro's THISFORM or THIS.Parent. The main difference here is that Visual FoxPro encapsulates the event code in the object that fires the event, while .NET points the object to a method in the actual form. Therefore, the Save() and Close() methods are actually members of the same object as the event method. This may be bad design on one hand, since object purists would point out that code that belongs to the button object should be a member of the button object. On the other hand, the event handling code defined on the form level can see protected methods of the form (see below), which promotes good design. In Visual FoxPro, methods that should be protected very often end up as public just to allow members access. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 261 OK, at this point we are ready to test our base form class. As mentioned above, I use the default form created when I added a new project as my test bench, and I recommend you do the same. Just add a button to the form and put the following code in the click event. Again, C# first: DataEntryBaseForm oBase = new _ DataEntryBaseForm(); oBase.Show(); The Visual Basic.NET version is very similar: Dim oBase As New DataEntryBaseForm() oBase.Show() Note that there is a "gotcha" for Visual Basic developers here. Unlike Visual Basic 6, where all forms can just be shown (which is kind of weird, when you think about it), .NET requires the object to be created before it can be displayed. Run your app, and click the Save button. As expected, a message box that says "Base Form Save" appears. Advertisement Creating a Customer Edit Form Class So far, so good. We are now ready to create individual subclasses. Right-click your solution in the Solution Explorer and select "Add Inherited Form". Specify a name for the new form class ("CustomerEditForm"). In the dialog shown in Figure 3, pick "DataEntryBaseForm". Doubleclick the new form in the Solution Explorer to edit it. Figure 4 shows the subclassed form in edit mode. Note that this form automatically shows three buttons, although we have not added any buttons to the form. Those three buttons have been inherited from the parent class. This is indicated by the darker background color of the inherited buttons (we will talk about this a little more further down). Here's the code (as always, first in C#) that was generated for us: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 262 Page | 263 to select the parent class of our new form. Figure 3 The Inheritance Picker is used Figure 4 Inherited controls are shown in dark-gray in edit mode (they are displayed normally in runtime mode). namespace CSInheritanceSample { using System; using System.Collections; using System.Core; using System.ComponentModel; using System.Drawing; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) using System.WinForms; public class CustomerEditForm : CSInheritanceSample.DataEntryBaseForm { private System.ComponentModel.Icontainer components; public CustomerEditForm() { InitializeComponent(); } // Form overrides dispose to clean up // the component list. public override void Dispose() { base.Dispose(); components.Dispose(); } private void InitializeComponent() { components = new System.ComponentModel.Container(); } } } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 264 The Visual Basic version is very similar: Imports System.ComponentModel Imports System.Drawing Imports System.WinForms Public Class CustomerEditForm Inherits _ VBInheritanceSample.DataEntryBaseForm Public Sub New() MyBase.New CustomerEditForm = Me ' This call is required by the ' WinForm Designer. InitializeComponent End Sub ' Form overrides dispose to clean up ' the component list. Overrides Public Sub Dispose() MyBase.Dispose components.Dispose End Sub #Region " Windows Form Designer code " 'Required by the WinForm Designer COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 265 Private components As _ System.ComponentModel.Container Dim WithEvents CustomerEditForm As _ VBInheritanceSample.DataEntryBaseForm Private Sub InitializeComponent() components = New _ System.ComponentModel.Container End Sub #End Region End Class None of this code really does anything for us. We could now add new code to this form, but the key is that we don't have to. Add another button to your test bench form and instantiate the new class with the following code: CustomerEditForm oCustomer = new _ CustomerEditForm(); oCustomer.Show(); Visual Basic: Dim oCustomer As New CustomerEditForm() oCustomer.Show() When you run the form, you will see that it behaves just like the original form, including all the message boxes. Note that you can also see the inheritance structure in the Class View Window (Figure 5). Visual Studio.NET displays parent classes as sub-items in the tree, which is somewhat against common sense, since the items we refer to as "child classes" are parent nodes in the tree. But, I guess we'll get used to it. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 266 Page | 267 Figure 5 The Class View shows the inheritance structure (although in a somewhat backwards fashion with the parent class as a child node in the tree). Adding new behavior in C# We can now extend the form's behavior by overriding methods in the subclass. This is done slightly differently in C# than in Visual Basic.NET. We will first take a look at the C# version. Add the following code to the CustomerEditForm C# class: public void Save() { MessageBox.Show("Subclassed Save"); } The method is almost identical to the method in the base class, with the exception of the text displayed in the message box. However, when we compile and run the form, we still see the old behavior and not the new message box. The problem is that the compiler looks at the code in the button event of the parent class and says "OK, we are calling the Save() method, so lets compile in the Save() method of the DataEntryBaseForm class...", which is correct logic, since the code that calls the method sits in the DataEntryBaseForm class. If we were to directly call the Save() method right in the code where we create the form, everything would work as expected: CustomerEditForm oCustomer = new CustomerEditForm(); oCustomer.Show(); oCustomer.Save(); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) The reason this works is that the compiler sees that we want to use the Save() method of the customer form, and compiles it in as expected. What we really want, however, is a runtime decision about which code to run ? not a compile-time decision. We can force the compiler to do so by using a "virtual" method, explained in detail below. For now, let's modify the method in Page | 268 the parent class (DataEntryBaseForm) as follows: public virtual void Save() { MessageBox.Show("Base Form Save"); } This tells the compiler to be a bit more careful when coming up with the compiled version of this code and to delay the decision about which code to call until the code is executed. In other words, we have now designed this method to be changed in subclasses. Since we have done that, the compiler requires an explicit indication of our desire to override the Save() method in the subclass, to avoid accidental override of significant behavior: public override void Save() { MessageBox.Show("Subclassed Save"); } Now, the compilation will work just fine, and we can execute the new form. When you click the OK or Apply button, the new message box will be displayed. In a real-world scenario, we would add more significant code, of course. Perhaps we would call a business object to save information, or we could even do some verifications right in the Save() method. We have just customized the original form by redefining behavior in the subclass. Of course, at this point, we've lost all behavior defined in the parent class (the terms "super class" and "parent class" can be used interchangeably and describe the class the current class inherits from). To also invoke the original behavior (known as the "default behavior"), we have to specifically invoke it. We can do so in our subclass in the following manner: public override void Save() { MessageBox.Show("Subclassed Save"); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) base.Save(); } The "base" pointer always refers to the parent class. When we run this code, both message boxes Page | 269 are displayed. First, the new one, and then the one from the base class. We could have changed the order by making the call to the parent class first: public override void Save() { base.Save(); MessageBox.Show("Subclassed Save"); } In fact, you could have made the call to the default behavior dependent on some condition: public override void Save() { MessageBox.Show("Subclassed Save"); if (false) { base.Save(); } } Obviously, "false" would be replaced by a real condition. Calling the default behavior can be very important. It gives us the freedom to easily add behavior to the parent class. For this reason, I always call the default behavior unless I know for a fact that I want to override it. This is true even if there is no code in the default method (which would always be the case in an abstract class, but it could also be the case in any other class). After all, we might just want to add new behavior later on. If you forgot to call the default behavior, you would have to go back through all your code and add the call. This would not just be a lot of work, but it's also a major threat to overall project quality. For this reason, I would make the call to the base class a habit. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Here's an example: Let's imagine we want to add information to a log file every time information is saved (we will simulate this with... you guessed it... a message box). We can easily do this by adding the following code to the DataEntryBaseForm class: public virtual void Save() Page | 270 { MessageBox.Show("Logging Information..."); MessageBox.Show("Base Form Save"); } Now, run the customer edit form, and you will see that the OK and Apply buttons now trigger 3 message boxes, although we've didn't change anything in the subclass. That's the power of inheritance! Adding new behavior in Visual Basic.NET As mentioned before, the Visual Basic.NET version is a little bit different. The main difference is that in Visual Basic.NET, all methods are virtual (just like in Visual FoxPro, by the way). This has implications as described in the "Virtual Methods" sidebar. However, we still have to define a new method that specifically overrides the parent method, and we still have to define the parent method as "overridable". Here is the method in the DataEntryBaseForm class: Public Overridable Sub Save() MessageBox.Show("Base Form Save") End Sub And, here is the method in the subclass: Public Overrides Sub Save() MessageBox.Show("Subclassed Save") End Sub You can compile and run this form (add a reference to the test bench form so you can launch the new form). When you click the OK button, you will see the new message box only, just like in the C# sample. To also call the method in the parent class, add the following code to the subclass: Public Overrides Sub Save() COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) MessageBox.Show("Subclassed Save") MyBase.Save() End Sub Page | 271 Just like in the C# sample, you could rearrange the order or make the call to the base class (in VB the reference is called "MyBase") dependent on some condition. Virtual Methods So, what exactly was the difference between the C# and the VB.NET implementation? And what exactly are "Virtual Methods"? To answer this question, we will have to take another look at the C# example. We created the customer form with the following code (and we could have called the Save() method right away since it is a public method): CustomerEditForm oCustomer = new CustomerEditForm(); oCustomer.Save(); We created a reference of type "CustomerEditForm" and used the "new" operator to create the form. We could have also written it this way: DataEntryBaseForm oCustomer = new _ CustomerEditForm(); oCustomer.Save(); In this case, the reference is of type "DataEntryBaseForm". However, this reference is capable of holding a reference to the customer form, since the CustomerEditForm class isa DataEntryBaseForm. Now, let's think about what the compiler does in this scenario. It sees we want to create a DataEntryBaseForm type class and we also want to call the Save() method. So, the compiler says "OK, one Save() method coming right up..." and compiles in the code defined in the Save() method of the DataEntryBaseForm (since this is the type of the reference). This will result in high performance code, but will also result in the wrong behavior, as far as we are concerned. We don't want the compiler to make the decision during compilation, but we want to call the appropriate method during runtime, depending on what object we actually instantiate. That's what's called a "virtual" method. We indicate a virtual method to the compiler by adding the COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) "virtual" keyword in C#. In Visual Basic.NET, all methods are virtual (note that this may result in slower code in case we don't want virtual methods, although it's not very likely that we would want that). Advertisement Multi-Level Subclassing At this point, Visual Basic 6 developers might say "OK, that's nice, but I don't see the big deal here. After all, this is similar to templates, with the exception that we can also add some code." Well, that's not quite correct, because we could now use the CustomerEditForm and subclass it to another level. This is very useful. Perhaps we have a client who likes our application, but would like the CustomerEditForm to look and/or behave differently. Rather than writing another customer edit form, we can simply subclass the CustomerEditForm and change only what the client wants. This keeps the general implementation easy to maintain, even if we have lots of specialized customer edit forms. The code for this would look just like the code we've already created. Imagine we want to create a customer edit form with an additional logo. Here's the code for that (C#): public class CustomerEditFormWithLogo : CSInheritanceSample.CustomerEditForm { // Code goes here.. } Or, in Visual Basic.NET: Public Class CustomerEditFormWithLogo Inherits VBInheritanceSample.CustomerEditForm ' Code goes here... End Class You can do this over as many levels as you want, although based on my own experience, it starts to get a bit confusing after more than 5 to 7 levels of subclassing. Also, keep in mind that we can subclass more than just the form. Perhaps we might subclass some textbox classes to use on the form. Imagine that we want the "Apply" button to be enabled only after changes have been made in at least one of the textboxes. We could create a textbox subclass that sets the enabled state of the "Apply" button after the first modification, then base COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 272 our form's textboxes on that subclass. Without that special textbox class, we would have to add that code to each textbox. What a nightmare! In many object-oriented languages, developers hardly ever use standard classes, such as a plain textbox. All those classes are usually subclassed into a developer's (or project's) own set of classes, allowing him to change behavior and visual characteristics across the project by making the change in one place, and one place only. We will see whether this becomes common practice in .NET, as well... What "Scope" does to Subclassing So far, all our example methods (Save and Cancel) were Public methods. This means that anybody can call those methods from anywhere (as long as a reference to the object is available). In Visual Basic 6, there also are "Private" methods. Those methods are visible only from within the class where they are defined (for Visual FoxPro developers, this is the same as "Hidden"). Private is available in .NET as well, but in most scenarios, "Protected" makes more sense. A protected method (or property) is protected from outside access just like a private member, but it can also be accessed in subclasses. This is usually very desirable, because it protects the class from improper use, yet does not force us to sacrifice flexibility in our subclasses. Note: The scope could also be "Internal" or "Protected Internal", which generally are similar to "Public" and "Protected", with the scope limited to the current namespace. This, in essence, is the equivalent to "friendship" scenarios used in other environments. (As you can see, most objectoriented concepts are available in similar fashion on all object-oriented environments, but the vocabulary used can be quite different.) Scope can also be applied to member objects. As we saw in Figure 4, the button objects couldn't be modified in the subclass because they were "private" objects. You can go back to the DataEntryBaseForm class and change the "Modifier" property of the "OK" and "Cancel" buttons to "Protected". Now, go back to the CustomerEditForm class and edit it (note that you will have to compile the project to make the change show up in the child class ? Visual FoxPro developers, I feel your pain). You will now see the form as in Figure 6. It may be a little hard to see, but the gray shade of the "OK" and "Cancel" buttons is slightly lighter than the "Apply" button, which is still "Private". Since we have access to "protected" members inside the subclass, we can change properties and even code attached to those objects. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 273 Page | 274 Figure 6 The OK and Cancel buttons have been changed from "Private" to "Protected", so they can be modified in the subclass. This is also indicated by the slightly lighter shade of gray (compared to the "Apply" button). Conclusion Inheritance is a rather simple mechanism that's relatively easy to learn, although it requires a change in the developer's thought processes. To me, inheritance is one of the most important new features in .NET ? especially in Visual Basic.NET. Trust me, folks. Once you get used to inheritance, it will be hard for you to ever imagine creating a serious software project without it. MULTIPLE DOCUMENT INTERFACE (MDI) APPLICATIONS A multiple document interface (MDI) is a graphical user interface in which multiple windows reside under a single parent window. Such systems often allow child windows to embed other windows inside them as well, creating complex nested hierarchies. This contrasts with the single document interfaces (SDI) where all windows are independent of each other. ADVANTAGES OF MULTIPLE DOCUMENT INTERFACE • With MDI, a single menu bar and/or toolbar is shared between all child windows, reducing clutter and increasing efficient use of the screen space. • An application's child windows can be hidden/shown/minimized/maximized as a whole. In this article, we will see how to create Multiple Document Interface in C#. We chose C# because it is one of the most popular programming languages. So, let’s start. CREATING THE APPLICATION • In Visual Studio, click on Start->New->Project. • Select Windows Forms Application from the available options. • Let’s give the application a name. I named it “MDIAppwithRichTextBox”. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) • Click on the “OK” button. A Windows.Forms application is created. • Right-click on the “Form1” in the design view and click on "Properties". • On the Properties window, scroll down to “Design” and change the “Name” property to “MDIContainer” from “Form1”. Now, in the Properties window, scroll down to “Window Style” section and change the “IsMdiContainer” property to “true”. The change of the client area of the form changes to grey after doing this. This property tells the program that the form can contain other forms. • Now, let’s add another form to the project. For that, right-click on the Project in Solution Explorer and select "Add" from the context menu. • Click on “Windows Form”. A window will appear. • Let’s name the form at the bottom of this window to “MyForm”. • Click on the “Add” button. A new form will be added to your project. This form will act as our edit area and will be contained in the MDIContainer form. We will shortly see how. • First, let’s add a RichTextBox to “MyFrom” form. From the toolbox, let’s drag and drop a RichTextBox to this form and go to the properties of the Richtextbox. • Scroll down to “Layout” section and change the “Dock” property to “Fill”. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 275 Page | 276 You will see that RichTextBox fills the entire client area of the form. • Now, let’s go to the first form “MDIContainer” and add a “MenuStrip” from the Toolbox-> Menus & Toolbars to the form. • You will see that a new text box appears at the top of the form within a strip. Now let’s create the menu. In the first Box type “File”. • A textbox will appear below it. Let’s create four submenu items. “New File”, “Open File”, “Save” and “Exit”. • Now, let’s create another topmost menu besides file. On the right of “File”, you will see another textbox. • Type “Insert” there and below that let’s create two submenus-“Text” and “Image”. • Now, let’s create another topmost menu. • On the right of “Insert” menu option, type “Edit”. • Below “Edit”, let’s create 7 submenus: “Undo”, “Redo”, “Mark Text”, “ForeColor”, “Font”, “Current Color”, “Current Font”, ”Cut”, ”Copy”, and “Paste”. • At last, let’s create another Menu item -> “CloseActiveForm”. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 277 This ends our menu section. Now, let’s double click on File->New File. This will create a new method in the code behind file. 1. private void newToolStripMenuItem_Click(object sender, EventArgs e) 2. { 3. } In this method, let’s add the following code. 1. private void newToolStripMenuItem_Click(object sender, EventArgs e) 2. { 3. MyFrom childform = new MyFrom(); 4. childform.MdiParent = this; 5. childform.Show(); 6. } Now, examine the code. The first line reads 1. MyFrom childform = new MyFrom(); It creates a new instance of “MyForm” form which we added to the project. The second line is 1. childform.MdiParent = this; It sets the MdiParent property of the instance of “MyForm”. We have set the MDIparent of this form to “this’ which is the current form -(“MDIContainer”) form. The last line is COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) 1. childform.Show(); This opens MyForm. This will open inside the client area of “MDIContainer” form. Let’s run the application and check it. In the running form, click on the “File >> New File” menu. It will open a form. You can click on “New File” many times and it will open multiple forms. Try writing in the form. You will see that you are able to write in any of the opened forms Page | 278 (which, in fact, are instances of “MyForm” which we added to the project). Now, let’s write the code for opening a new file. The files which can be opened in Richtextbox can either be text files or a “*.rtf” rich text file. So, let’s drag and drop an “OpenFileDialog” to “MDIContainer” form from Toolbox->Dialogs. Now, double click on the second submenu under “File”, i.e., “Open File”. A new method will be generated in the code behind. 1. private void openToolStripMenuItem_Click(object sender, EventArgs e) 2. { 3. } In this method, let’s add the following code. 1. private void openToolStripMenuItem_Click(object sender, EventArgs e) 2. 3. 4. 5. { openFileDialog1.InitialDirectory = Environment.GetFolderPath(Environment.Spe cialFolder.MyDocuments); openFileDialog1.RestoreDirectory = true; openFileDialog1.Filter = "Text Files (*.txt)|*.txt| Rich Text Format (*.rtf)|*.rtf|" + "All Files (*.*)|*.*"; 6. if (openFileDialog1.ShowDialog() == DialogResult.OK) 7. { 8. String fileName = openFileDialog1.FileName; 9. if (fileName.Length != 0) 10. { 11. try 12. { 13. MyFrom childform = new MyFrom(); 14. childform.OpenFile(openFileDialog1.FileName); 15. childform.MdiParent = this; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) 16. childform.Show(); 17. } 18. catch 19. { 20. MessageBox.Show(String.Format("{0} is not " + "a valid file", fileName), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 21. } 22. } 23. 24. } } • The first line sets the directory to open by default when the openFile dialog opens. We have set it to “MyDocuments” folder. • The second line sets the default directory when closing File dialogue, i.e., it will be set to the current directory you have used while opening the file. • The third line sets the filter property of the "Open File" dialog. We have set three types *.txt , *.rtf, and *.*. These three types of files will be shown in the openFile dialog when you try to open any file. • The fourth line tries to open the openFile dialog and if the result is “OK”, the code in the following section will be executed. • In the try catch block, let’s add code to open a new instance of “MyForm”. I have added a new method “OpenFile(stringfileName)” in the code behind in “MyForm” which is to read the file provided by “MDIContainer” Form into its richtext box. We will see it soon. • Here, we have called its “OpenFile” method and passed the file name with full path, which we will select in the openFile dialog. • In the catch block, we have added a message box to show the error encountered. Now, let’s examine the “OpenFile” method we have added in “MyForm”. 1. public void OpenFile(string fileName) 2. 3. { string strExt; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 279 4. strExt = System.IO.Path.GetExtension(fileName); 5. strExt = strExt.ToUpper(); 6. if (strExt == ".RTF") 7. { 8. Page | 280 richTextBox1.LoadFile(fileName, RichTextBoxStreamType.RichText); 9. } 10. else if(strExt == ".TXT") 11. { 12. richTextBox1.LoadFile(fileName, RichTextBoxStreamType.PlainText); 13. } 14. else 15. { 16. System.IO.StreamReader txtReader; 17. txtReader = new System.IO.StreamReader(fileName); 18. richTextBox1.Text = txtReader.ReadToEnd(); 19. txtReader.Close(); 20. txtReader = null; 21. richTextBox1.SelectionStart = 0; 22. richTextBox1.SelectionLength = 0; 23. } 24. richTextBox1.Modified = false; 25. this.Text = "Editor: " + fileName; 26. } First, we get the extension of file we are going to open. If it is a *.rtf file, it will be opened with the following options. 1. richTextBox1.LoadFile(fileName, RichTextBoxStreamType.RichText); If it is a *.txt file, it will be opened with the following options. 1. richTextBox1.LoadFile(fileName, RichTextBoxStreamType.PlainText); Otherwise, we use the System.IO.StreamReader to read the file. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Lastly, we set the title text of the form to the filename. 1. this.Text = "Editor: " + fileName; Try testing the application and opening a file. Now, let’s see the code for saving the file. For that, let’s drag and drop a “SaveFileDialog” to “MDIContainer” form. Now, double-click on the “Save File” submenu. The method will be generated in the code behind. Let’s add the following code to it. 1. private void saveToolStripMenuItem_Click(object sender, EventArgs e) 2. 3. { *)|*.*"; saveFileDialog1.Filter = "Text Files (*.txt)|*.txt|RTF Files (*.rtf)|*.rtf|All Files(*. 4. saveFileDialog1.AddExtension = true; 5. if (saveFileDialog1.ShowDialog() == DialogResult.OK) 6. { 7. Form activeChildForm = this.ActiveMdiChild; 8. if (activeChildForm != null) 9. { 10. RichTextBox RichtxtEditor = activeChildForm.ActiveControl as RichTextB ox; 11. if (RichtxtEditor != null) 12. { 13. string extension = System.IO.Path.GetExtension(saveFileDialog1.FileName); if (extension.ToLower() == ".txt") /*saveFileDialog.FilterIndex==1*/ 14. 15. RichtxtEditor.SaveFile(saveFileDialog1.FileName, RichTextBoxStreamT ype.PlainText); else if(extension.ToLower()==".rtf") 16. 17. RichtxtEditor.SaveFile(saveFileDialog1.FileName, RichTextBoxStreamT ype.RichText); } 18. 19. } } COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 281 20. } The first line sets the filter for file types to be saved as. The second line is 1. saveFileDialog1.AddExtension = true; This sets the AddExtension property to true . It adds an extension according to the file type selected in saveFile dialog if it is omitted. The next line reads 1. if (saveFileDialog1.ShowDialog() == DialogResult.OK) It opens the saveFile dialog if the dialog result is OK. The next line is 1. Form activeChildForm = this.ActiveMdiChild; It is used to get the active child form (active MyForm in our case). The next line reads 1. if (activeChildForm != null) 2. { It checks if there is an active child form. In the next line, we get the Richtextbox of the active child form, 1. RichTextBox RichtxtEditor = activeChildForm.ActiveControl as RichTextBox; The next line checks if the Control(RichTextBox) is available. 1. if (activeChildForm != null) The next line gets the extension of file. 1. var extension = System.IO.Path.GetExtension(saveFileDialog1.FileName); The next line checks the extension of the file and saves it accordingly. 1. if (RichtxtEditor != null) 2. { 3. string extension = System.IO.Path.GetExtension(saveFileDialog1.FileName); 4. 5. 6. if (extension.ToLower() == ".txt") /*saveFileDialog.FilterIndex==1*/ RichtxtEditor.SaveFile(saveFileDialog1.FileName, RichTextBoxStreamT ype.PlainText); else if(extension.ToLower()==".rtf") COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 282 7. RichtxtEditor.SaveFile(saveFileDialog1.FileName, RichTextBoxStreamT ype.RichText); } 8. } Now, let’s try to insert an image and some text. For inserting text, let’s double click on the “Text” submenu under “Insert” menu. A new method will be generated in the code behind. Let’s add the following code to it. 1. private void textToolStripMenuItem_Click(object sender, EventArgs e) 2. { 3. Form activeChildForm = this.ActiveMdiChild; 4. if (activeChildForm != null) 5. { 6. RichTextBox RichtxtEditor = activeChildForm.ActiveControl as RichTextBox; 7. if (RichtxtEditor != null) 8. { 9. DataFormats.Format myFormat = DataFormats.GetFormat(DataFormats.Tex t); 10. 11. if (RichtxtEditor.CanPaste(myFormat)) 12. { 13. RichtxtEditor.Paste(myFormat); 14. } 15. } 16. 17. } } As previously, we get the active richtextbox; then set the data format which can be set to access the text on clipboard. Then, paste the text to the richtextbox. Now, let’s add the code for inserting an image into the rich text box. Let’s double click on the “Image” submenu under the “Insert” menu. A stub code will be generated in the code behind. Let’s write the following code to it. 1. private void imageToolStripMenuItem_Click(object sender, EventArgs e) COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 283 2. { 3. openFileDialog1.Title = "Insert Image"; 4. openFileDialog1.DefaultExt = "bmp"; 5. openFileDialog1.Filter = "Bitmap Files|*.bmp|JPEG Files|*.jpg|GIF Files|*.gif|PN Page | 284 G Files|*.png"; 6. openFileDialog1.FilterIndex = 1; 7. 8. if (openFileDialog1.ShowDialog() == DialogResult.OK) 9. { 10. if (openFileDialog1.FileName == "") 11. { return; 12. 13. } 14. 15. try 16. { 17. Form activeChildForm = this.ActiveMdiChild; 18. if (activeChildForm != null) 19. { 20. tBox; RichTextBox RichtxtEditor = activeChildForm.ActiveControl as RichTex 21. if (RichtxtEditor != null) 22. { 23. string theImagePath1 = openFileDialog1.FileName; 24. Image img; 25. img = Image.FromFile(theImagePath1); 26. Clipboard.SetDataObject(img); 27. DataFormats.Format df; 28. df = DataFormats.GetFormat(DataFormats.Bitmap); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) 29. if (RichtxtEditor.CanPaste(df)) 30. { 31. RichtxtEditor.Paste(df); 32. } 33. } 34. } 35. } 36. catch 37. { 38. MessageBox.Show("Unable to insert image.", "Error", MessageBoxButtons. OK, MessageBoxIcon.Error); 39. } 40. 41. } } The first line sets the title for openFile dialog. We have seen the filter in earlier openFile dialog so that’s understood. We come directly to the highlighted code, i.e., string theImagePath1 = openFileDialog1.FileName; Here, we get the full path of the image file selected in openFile dialog. In the next line, i.e., 1. Image img; 2. img = Image.FromFile(theImagePath1); We get the image form where we declare an image file and set the image in it. In the next line, we set it on the clipboard of Windows so that we can paste it from there. 1. Clipboard.SetDataObject(img); The next lines are obvious. We use these as we have done in the Paste text earlier. 1. DataFormats.Format df; 2. df = DataFormats.GetFormat(DataFormats.Bitmap); 3. if (RichtxtEditor.CanPaste(df)) COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 285 4. { 5. 6. RichtxtEditor.Paste(df); } Now, let’s write the code for the Edit menu’s submenus. First, let’s write the code for “Undo” submenu. Double-click on the “Undo” submenu. The code will be generated in the code behind. Let’s write the following code. 1. private void undoToolStripMenuItem_Click(object sender, EventArgs e) 2. { 3. Form activeChildForm = this.ActiveMdiChild; 4. if (activeChildForm != null) 5. { 6. RichTextBox RichtxtEditor = activeChildForm.ActiveControl as RichTextBox; 7. if (RichtxtEditor != null) 8. { 9. if (RichtxtEditor.CanUndo) 10. { 11. activeChildForm.SuspendLayout(); 12. RichtxtEditor.Undo(); 13. activeChildForm.ResumeLayout(); 14. } 15. } 16. 17. } } Here, we call the suspendlayout method of the active child form. This suspends the layout of the form. Then we call the undo method of richtextbox and then we resume the layout. Similarly, for Redo. 1. private void redoToolStripMenuItem_Click(object sender, EventArgs e) 2. 3. { Form activeChildForm = this.ActiveMdiChild; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 286 4. if (activeChildForm != null) 5. { 6. RichTextBox RichtxtEditor = activeChildForm.ActiveControl as RichTextBox; 7. if (RichtxtEditor != null) 8. { 9. if (RichtxtEditor.CanRedo == true) 10. { 11. if (RichtxtEditor.RedoActionName != "Delete") 12. { 13. activeChildForm.SuspendLayout(); 14. RichtxtEditor.Redo(); 15. activeChildForm.ResumeLayout(); 16. } 17. } 18. } 19. 20. } } We call the “Redo” method of the richtextbox. Next, we will see the mark text menu option for coloring the background of the selected text. • First, let’s add “colorDialog” to the “MDIContainer” Form. • Let’s go to Toolbox->Dialogs->colorDialog and double click on it. • Double click on “Mark Text” submenu option under “Edit” menu in “MDIContainer” form. A stub code will be generated in the code behind. • Let’s write the following code in it. 1. private void markTextToolStripMenuItem_Click(object sender, EventArgs e) 2. { 3. 4. Form activeChildForm = this.ActiveMdiChild; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 287 5. if (activeChildForm != null) 6. { 7. RichTextBox RichtxtEditor = activeChildForm.ActiveControl as RichTextB ox; 8. if (RichtxtEditor != null) 9. { 10. if (colorDialog1.ShowDialog() == DialogResult.OK) 11. { 12. if (RichtxtEditor.SelectionLength > 0) 13. { 14. RichtxtEditor.SelectionBackColor = colorDialog1.Color; 15. RichtxtEditor.DeselectAll(); 16. } 17. } 18. } 19. 20. } } 21. } We will see the marked text. The first line is 1. RichtxtEditor.SelectionBackColor = colorDialog1.Color; Here, we set the backcolor of the selected text to the color of the colorDialog. Then, in the next line, we deselect the text. Now, let’s see how to set the forecolor of the selected text. Let’s double click on ForeColor submenu option and in the code behind add the following code. 1. private void foreColorToolStripMenuItem_Click(object sender, EventArgs e) 2. { 3. Form activeChildForm = this.ActiveMdiChild; 4. if (activeChildForm != null) 5. { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 288 6. RichTextBox RichtxtEditor = activeChildForm.ActiveControl as RichTextBox; 7. if (RichtxtEditor != null) 8. { 9. if (colorDialog1.ShowDialog() == DialogResult.OK) 10. { 11. RichtxtEditor.SelectionColor = colorDialog1.Color; 12. RichtxtEditor.DeselectAll(); 13. } 14. } 15. 16. } } In the first line, we set the forecolor of the selected text. Then, we deselect all the text. Now, let’s see how to set the font of the selected text. Drag and drop a fontDialog to the “MDIContainer” form. Now, double-click on the “Font” submenu option. Now, let’s write the following code in the code behind. 1. private void foreColorToolStripMenuItem_Click(object sender, EventArgs e) 2. { 3. Form activeChildForm = this.ActiveMdiChild; 4. if (activeChildForm != null) 5. { 6. RichTextBox RichtxtEditor = activeChildForm.ActiveControl as RichTextBox; 7. if (RichtxtEditor != null) 8. { 9. if (colorDialog1.ShowDialog() == DialogResult.OK) 10. { 11. if (RichtxtEditor.SelectionLength > 0) 12. { 13. RichtxtEditor.SelectionColor = colorDialog1.Color; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 289 14. RichtxtEditor.DeselectAll(); 15. } 16. } 17. } 18. 19. Page | 290 } } In the first line, we set the font of the selected text as per the font selected in fontDialog. In the next line, we deselect all the text. Now, let’s see how to set the current default color of the text. Let’s double click on the “Current Color” submenu option and go to the code behind and add the following code. 1. private void currentTextToolStripMenuItem_Click(object sender, EventArgs e) 2. { 3. Form activeChildForm = this.ActiveMdiChild; 4. if (activeChildForm != null) 5. { 6. RichTextBox RichtxtEditor = activeChildForm.ActiveControl as RichTextBox; 7. if (RichtxtEditor != null) 8. { 9. if (colorDialog1.ShowDialog() == DialogResult.OK) 10. { 11. RichtxtEditor.ForeColor = colorDialog1.Color; 12. } 13. } 14. 15. } } Here, in the line RichtxtEditor.ForeColor = colorDialog1.Color; we set the current color of text. This will be the color of the text as we type in some new text. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Now, let’s set the current font of text. Let’s double click on “Current Font” menu option and in the code behind, write the following code. 1. private void currentFontToolStripMenuItem_Click(object sender, EventArgs e) 2. { 3. Form activeChildForm = this.ActiveMdiChild; 4. if (activeChildForm != null) 5. { 6. RichTextBox RichtxtEditor = activeChildForm.ActiveControl as RichTextBox; 7. if (RichtxtEditor != null) 8. { 9. if (fontDialog1.ShowDialog() == DialogResult.OK) 10. { 11. RichtxtEditor.Font = fontDialog1.Font; 12. } 13. } 14. 15. } } Here, we set the current font of the richtextbox from the fontdialog selection. Now, let’s see how to “Cut” from richtextbox. Double click on “Cut” submenu option and in the code-behind, let’s write the following code. 1. private void cutToolStripMenuItem_Click(object sender, EventArgs e) 2. { 3. Form activeChildForm = this.ActiveMdiChild; 4. if (activeChildForm != null) 5. { 6. RichTextBox RichtxtEditor = activeChildForm.ActiveControl as RichTextBox; 7. if (RichtxtEditor != null) 8. { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 291 if (RichtxtEditor.SelectionLength > 0) 9. 10. RichtxtEditor.Cut(); 11. } 12. 13. } Page | 292 } If selection is not zero, we cut the text or image or both. Similarly, for copy, we double click on the “Copy” submenu and write the following code in the code behind file. 1. private void copyToolStripMenuItem_Click(object sender, EventArgs e) 2. { 3. Form activeChildForm = this.ActiveMdiChild; 4. if (activeChildForm != null) 5. { 6. RichTextBox RichtxtEditor = activeChildForm.ActiveControl as RichTextBox; 7. if (RichtxtEditor != null) 8. { if (RichtxtEditor.SelectionLength > 0) 9. 10. RichtxtEditor.Copy(); 11. } 12. 13. } } Here, we copy the selection if it is not zero. For pasting, we double click on the“Paste” submenu and in the code-behind file, we write the following code. 1. private void pasteToolStripMenuItem_Click(object sender, EventArgs e) 2. { 3. Form activeChildForm = this.ActiveMdiChild; 4. if (activeChildForm != null) COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) 5. { 6. RichTextBox RichtxtEditor = activeChildForm.ActiveControl as RichTextBox; 7. if (RichtxtEditor != null) 8. { 9. RichtxtEditor.Paste(); 10. } 11. 12. } } Here, we paste the cut or copied selection. Now, to close the currently active Form, we write the following code. 1. private void closeActiveFormToolStripMenuItem_Click(object sender, EventArgs e) 2. { this.ActiveMdiChild.Close(); 3. 4. } Now, let’s go to “MyForm” and in its code behind, let’s write the following. 1. public MyFrom() 2. { 3. InitializeComponent(); 4. this.richTextBox1.EnableAutoDragDrop = true; 5. this.richTextBox1.AcceptsTab = true; 6. this.richTextBox1.WordWrap = true; 7. this.richTextBox1.ScrollBars = RichTextBoxScrollBars.Both; 8. this.richTextBox1.ShortcutsEnabled = true; 9. 10. } 11. 12. this.richTextBox1.EnableAutoDragDrop = true; this enables drag and drop to Richtextb ox COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 293 13. this.richTextBox1.AcceptsTab = true; this enables tabs 14. this.richTextBox1.WordWrap = true; this enables Word wrap according to the width of your form 15. this.richTextBox1.ScrollBars = RichTextBoxScrollBars.Both; This enables scrollbars in the richtextbox 16. this.richTextBox1.ShortcutsEnabled = true; This enables the shortcut keys in RichTextB ox. The following are the shortcut keys, • CTRL+Z • CTRL+E • CTRL+C • CTRL+Y • CTRL+X • CTRL+BACKSPACE • CTRL+V • CTRL+DELETE • CTRL+A • SHIFT+DELETE • CTRL+L • SHIFT+INSERT • CTRL+R Summary We saw in this article that Multiple Document Interface can be created using Windows.Forms Application. It is easy and very useful because it enables users to work with multiple documents at the same time. MDI applications can be used for a variety of purposes - for example, working on one document while referring to another document, viewing different presentations of the same information, viewing multiple Web sites at the same time, and any task that requires multiple reference points and work areas at the same time. Examples of MDI Applications are, • Visual Studio • Adobe Photoshop • Google Chrome COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 294 • Microsoft Word 2003 • Microsoft Excel 2003 etc. This completes our simple MDI with RichTextBox tutorial. You can play with it and add advanced features like indenting text, bulleting etc. You can check the original application attached to this article. Console-based applications CONSOLE-BASED APPLICATIONS Console programs are easy to develop, because console based applications perform all their input and output at the command line, they are ideal for quickly trying out language features and writing command-line utilities. If you have ever learned a programming language, you know that they all start with the "Hello, world!" program. Here also we start with the "Hello, world!". Hello World - Your First Program In order to create a C# console based application 1. Open your Visual Studio 2. On the File menu, click New Project. Then the New Project dialog box appears. This dialog box lists the different default application types. 3. Select Console Application as your project type and change the name of your application at the bottom textbox. If you are npt comfortable with default location, you can always enter a new path if you want. 4. Then Click OK. After click OK button, you will get a screen like the following picture. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 295 Page | 296 Here in the following program, we just print a "Hello, world!" message only. So copy and paste the following command in the main code block. Here you can see the full source code. After enter the command, the next step is to run the program. You can run your program using Ctrl+F5 . Then Visual Studio will keep the console window open, until you press a key. You will get screen look like the following picture. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Now you created your first program in Visual Studio. HOW TO STOP C# CONSOLE APPLICATIONS OF CLOSING AUTOMATICALLY The first program is to run your application by using Ctrl+F5, so the console window will remain open until you press a key. The disadvantage of this (Ctrl+F5) is that you lose Visual Studio's debug information. If you run your console application by using F5 instead of Ctrl+F5 , you can Page | 297 see the window will disappear suddenly. It is because you program is finished. When console applications have completed executing and return from their main method, the associated console window automatically closes. This is expected behavior. Prevent a C# Console Application from closing when it finishes If you want to keep the application open for debugging purposes, you'll need to instruct the computer to wait for a key press before ending the app and closing the window. In this case you can use Console.ReadLine() to wait for the user to Enter or Console.ReadKey to wait for any key. Full Source: C# Command Line Parameters In some situations, you have to send command line parameters to your application. When you pass arguments, the command line input, read from the standard entry point as string array. The arguments of the Main method is a String array that represents the command-line arguments. Usually you determine whether arguments exist by testing the Length property. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) The main program accept arguments in the order of args[0], args[1] etc. The following program shows how to display all parameters enter to the console application. Page | 298 How to pause console application System.Threading.Thread.Sleep() will delay your programs. It receives a value indicating the number of milliseconds to wait. This can be useful for waiting on an external application or task. When you run the above program, it will wait for 5 seconds and exit from application. How do I correctly exit from a console application A console application will just terminate when it's done, generally when it runs to the end of its Main entry point method. A "return" will achieve this. TUTORIAL: CREATE A SIMPLE C# CONSOLE APP IN VISUAL STUDIO (PART 1 OF 2) In this tutorial, you'll use Visual Studio to create and run a C# console app and explore some features of the Visual Studio integrated development environment (IDE) while you do so. This tutorial is part 1 of a two-part tutorial series. In this tutorial, you will: • Create a Visual Studio project. • Create a C# console app. • Debug your app. • Close your app. • Inspect your complete code. In part 2, you'll extend this app with additional projects, debugging tricks, and reference 3rd party packages. Prerequisites You must have Visual Studio installed. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) If you haven't already installed Visual Studio, go to the Visual Studio downloads page to install it for free. Create a project To start, we'll create a C# application project. The project type comes with all the template files you'll need, before you've even added anything! 1. Open Visual Studio. 2. On the start window, choose Create a new project. 3. In the Create a new project window, choose C# from the Language list. Next, choose Windows from the Platform list and Console from the project types list. After you apply the language, platform, and project type filters, choose the Console Application template, and then choose Next. Note If you do not see the Console Application template, you can install it from the Create a new project window. In the Not finding what you're looking for? message, choose the Install more tools and features link. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 299 Then, in the Visual Studio Installer, choose the .NET Core cross-platform development workload. After that, choose the Modify button in the Visual Studio Installer. You might be prompted to save your work; if so, do so. Next, choose Continue to install the workload. Then, return to step 2 in this "Create a project" procedure. 4. In the Configure your new project window, type or enter Calculator in the Project name box. Then, choose Next. 5. In the Additional information window, .NET Core 3.1 should already be selected for your target framework. If not, select .NET Core 3.1. Then, choose Create. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 300 Page | 301 Visual Studio opens your new project, which includes default "Hello World" code. Create the app First, we'll explore some basic integer math in C#. Then, we'll add code to create a basic calculator. After that, we'll debug the app to find and fix errors. And finally, we'll refine the code to make it more efficient. Explore integer math Let's start with some basic integer math in C#. In the code editor, delete the default "Hello World" code. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 302 Specifically, delete the line that says, Console.WriteLine("Hello World!");. 1. In its place, type the following code: C#Copy int a = 42; int b = 119; int c = a + b; Console.WriteLine(c); Console.ReadKey(); Notice that when you do so, the IntelliSense feature in Visual Studio offers you the option to autocomplete the entry. Note The following animation isn't intended to duplicate the preceding code. It's intended only to show how the autocomplete feature works. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 303 2. Choose the green Start button next to Calculator to build and run your program, or press F5. A console window opens that reveals the sum of 42 + 119, which is 161. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) 3. (Optional) You can change the operator to change the result. For example, you can change the + operator in the int c = a + b; line of code to - for subtraction, * for multiplication, or / for division. Then, when you run the program, the result changes, too. 4. Close the console window. Add code to create a calculator Let's continue by adding a more complex set of calculator code to your project. 1. Delete all the code you see in the code editor. 2. Enter or paste the following new code into the code editor: C#Copy using System; namespace Calculator { class Program { static void Main(string[] args) { // Declare variables and then initialize to zero. int num1 = 0; int num2 = 0; // Display title as the C# console calculator app. Console.WriteLine("Console Calculator in C#\r"); Console.WriteLine("------------------------\n"); // Ask the user to type the first number. Console.WriteLine("Type a number, and then press Enter"); num1 = Convert.ToInt32(Console.ReadLine()); // Ask the user to type the second number. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 304 Console.WriteLine("Type another number, and then press Enter"); num2 = Convert.ToInt32(Console.ReadLine()); // Ask the user to choose an option. Console.WriteLine("Choose an option from the following list:"); Console.WriteLine("\ta - Add"); Console.WriteLine("\ts - Subtract"); Console.WriteLine("\tm - Multiply"); Console.WriteLine("\td - Divide"); Console.Write("Your option? "); // Use a switch statement to do the math. switch (Console.ReadLine()) { case "a": Console.WriteLine($"Your result: {num1} + {num2} = " + (num1 + num2)); break; case "s": Console.WriteLine($"Your result: {num1} - {num2} = " + (num1 - num2)); break; case "m": Console.WriteLine($"Your result: {num1} * {num2} = " + (num1 * num2)); break; case "d": Console.WriteLine($"Your result: {num1} / {num2} = " + (num1 / num2)); break; } // Wait for the user to respond before closing. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 305 Console.Write("Press any key to close the Calculator console app..."); Console.ReadKey(); } } Page | 306 } 3. Choose Calculator to run your program, or press F5. A console window opens. 4. View your app in the console window, and then follow the prompts to add the numbers 42 and 119. Your app should look similar to the following screenshot: Add functionality to the calculator Let's tweak the code to add further functionality. Add decimals The calculator app currently accepts and returns whole numbers. But, it will be more precise if we add code that allows for decimals. As in the following screenshot, if you run the app and divide number 42 by the number 119, your result is 0 (zero), which isn't exact. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 307 Let's fix the code so that it handles decimals. 1. Press Ctrl + H to open the Find and Replace control. 2. Change each instance of the int variable to float. Make sure that you toggle Match case (Alt+C) and Match whole word (Alt+W) in the Find and Replace control. 3. Run your calculator app again and divide the number 42 by the number 119. Notice that the app now returns a decimal numeral instead of zero. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 308 However, the app produces only a decimal result. Let's make a few more tweaks to the code so that the app can calculate decimals too. 1. Use the Find and Replace control (Ctrl + H) to change each instance of the float variable to double, and to change each instance of the Convert.ToInt32 method to Convert.ToDouble. 2. Run your calculator app and divide the number 42.5 by the number 119.75. Notice that the app now accepts decimal values and returns a longer decimal numeral as its result. (We'll fix the number of decimal places in the Revise the code section.) Debug the app COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) We've improved on our basic calculator app, but it doesn't yet have fail safes in place to handle exceptions, such as user input errors. For example, if you try to divide a number by zero, or enter an alpha character when the app expects a numeric character (or vice versa), the app might stop working, return an error, or return an unexpected nonnumeric result. Page | 309 Let's walk through a few common user input errors, locate them in the debugger if they appear there, and fix them in the code. Tip For more information about the debugger and how it works, see the First look at the Visual Studio debugger page. Fix the "divide by zero" error When you try to divide a number by zero, the console app might freeze and then show you what's wrong in the code editor. Note Sometimes, the app doesn't freeze and the debugger won't show a divide-by-zero error. Instead, the app might return an unexpected nonnumeric result, such as an infinity symbol. The following code fix still applies. Let's change the code to handle this error. 1. Delete the code that appears directly between case "d": and the comment that says // Wait for the user to respond before closing. 2. Replace it with the following code: C#Copy // Ask the user to enter a non-zero divisor until they do so. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) while (num2 == 0) { Console.WriteLine("Enter a non-zero divisor: "); num2 = Convert.ToInt32(Console.ReadLine()); } Console.WriteLine($"Your result: {num1} / {num2} = " + (num1 / num2)); break; } After you add the code, the section with the switch statement should look similar to the following screenshot: Now, when you divide any number by zero, the app will ask for another number. Even better: It won't stop asking until you provide a number other than zero. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 310 Page | 311 Fix the "format" error If you enter an alpha character when the app expects a numeric character (or vice versa), the console app freezes. Visual Studio then shows you what's wrong in the code editor. To fix this error, we must refactor the code that we've previously entered. Revise the code Rather than rely on the program class to handle all the code, we'll divide our app into two classes: Calculator and Program. The Calculator class will handle the bulk of the calculation work, and the Program class will handle the user interface and error-capturing work. Let's get started. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) 1. Delete everything in the Calculator namespace between its opening and closing braces: C#Copy using System; Page | 312 namespace Calculator { } 2. Next, add a new Calculator class, as follows: C#Copy class Calculator { public static double DoOperation(double num1, double num2, string op) { double result = double.NaN; // Default value is "not-a-number" which we use if an operation, such as division, could result in an error. // Use a switch statement to do the math. switch (op) { case "a": result = num1 + num2; break; case "s": result = num1 - num2; break; case "m": result = num1 * num2; break; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) case "d": // Ask the user to enter a non-zero divisor. if (num2 != 0) { Page | 313 result = num1 / num2; } break; // Return text for an incorrect option entry. default: break; } return result; } } 3. Then, add a new Program class, as follows: C#Copy class Program { static void Main(string[] args) { bool endApp = false; // Display title as the C# console calculator app. Console.WriteLine("Console Calculator in C#\r"); Console.WriteLine("------------------------\n"); while (!endApp) { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) // Declare variables and set to empty. string numInput1 = ""; string numInput2 = ""; double result = 0; // Ask the user to type the first number. Console.Write("Type a number, and then press Enter: "); numInput1 = Console.ReadLine(); double cleanNum1 = 0; while (!double.TryParse(numInput1, out cleanNum1)) { Console.Write("This is not valid input. Please enter an integer value: "); numInput1 = Console.ReadLine(); } // Ask the user to type the second number. Console.Write("Type another number, and then press Enter: "); numInput2 = Console.ReadLine(); double cleanNum2 = 0; while (!double.TryParse(numInput2, out cleanNum2)) { Console.Write("This is not valid input. Please enter an integer value: "); numInput2 = Console.ReadLine(); } // Ask the user to choose an operator. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 314 Console.WriteLine("Choose an operator from the following list:"); Console.WriteLine("\ta - Add"); Console.WriteLine("\ts - Subtract"); Console.WriteLine("\tm - Multiply"); Console.WriteLine("\td - Divide"); Console.Write("Your option? "); string op = Console.ReadLine(); try { result = Calculator.DoOperation(cleanNum1, cleanNum2, op); if (double.IsNaN(result)) { Console.WriteLine("This operation will result in a mathematical error.\n"); } else Console.WriteLine("Your result: {0:0.##}\n", result); } catch (Exception e) { Console.WriteLine("Oh no! An exception occurred trying to do the math.\n - Details: " + e.Message); } Console.WriteLine("------------------------\n"); // Wait for the user to respond before closing. Console.Write("Press 'n' and Enter to close the app, or press any other key and Enter to continue: "); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 315 if (Console.ReadLine() == "n") endApp = true; Console.WriteLine("\n"); // Friendly linespacing. } return; } } 4. Choose Calculator to run your program, or press F5. 5. Follow the prompts and divide the number 42 by the number 119. Your app should look similar to the following screenshot: Notice that you have the option to enter more equations until you choose to close the console app. And, we've also reduced the number of decimal places in the result. Close the app 1. If you haven't already done so, close the calculator app. 2. Close the Output pane in Visual Studio. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 316 Page | 317 3. In Visual Studio, press Ctrl+S to save your app. Add Git source control Now that you've created your app, you might want to add it to a Git repository. We've got you covered; Visual Studio makes that process easy with Git tools you can use directly from the IDE. Tip Git is the most widely used modern version control system, so whether you're a professional developer or if you're learning how to code, Git can be very useful to you. If you are new to Git, the https://git-scm.com/ website is a good place to start. There, you’ll find cheat sheets, a popular online book, and Git Basics videos. To associate your code with Git, you start by creating a new Git repository where your code is located. Here's how. 1. In the status bar at the bottom-right corner of Visual Studio, select the Add to Source Control button, and then select Git. 2. In the Create a Git repository dialog box, sign in to GitHub. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 318 The repository name is auto-populated based on your folder location. By default, your new repository is private, which means you're the only one who can access it. Tip Whether your repository is public or private, it's best to have a remote backup of your code stored securely on GitHub even if you aren't working with a team. This also makes your code available to you no matter what computer you're using. 3. Select Create and Push. After you've created your repository, you'll see status details in the status bar. The first icon with the arrows shows how many outgoing/incoming commits are in your current branch. You can use this icon to pull any incoming commits or push any outgoing commits. You can also choose to view these commits first, too. To do so, click the icon, and then select View Outgoing/Incoming. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) The second icon with the pencil shows the number of uncommitted changes to your code. You can click this icon to view those changes in the Git Changes window. Review: code complete During this tutorial, we've made a lot of changes to the calculator app. The app now handles computing resources more efficiently, and it handles most user input errors. Here's the complete code, all in one place: C#Copy using System; namespace Calculator { class Calculator { public static double DoOperation(double num1, double num2, string op) { double result = double.NaN; // Default value is "not-a-number" which we use if an operation, such as division, could result in an error. // Use a switch statement to do the math. switch (op) { case "a": result = num1 + num2; break; case "s": result = num1 - num2; break; case "m": COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 319 result = num1 * num2; break; case "d": // Ask the user to enter a non-zero divisor. if (num2 != 0) { result = num1 / num2; } break; // Return text for an incorrect option entry. default: break; } return result; } } class Program { static void Main(string[] args) { bool endApp = false; // Display title as the C# console calculator app. Console.WriteLine("Console Calculator in C#\r"); Console.WriteLine("------------------------\n"); while (!endApp) { COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 320 // Declare variables and set to empty. string numInput1 = ""; string numInput2 = ""; double result = 0; // Ask the user to type the first number. Console.Write("Type a number, and then press Enter: "); numInput1 = Console.ReadLine(); double cleanNum1 = 0; while (!double.TryParse(numInput1, out cleanNum1)) { Console.Write("This is not valid input. Please enter an integer value: "); numInput1 = Console.ReadLine(); } // Ask the user to type the second number. Console.Write("Type another number, and then press Enter: "); numInput2 = Console.ReadLine(); double cleanNum2 = 0; while (!double.TryParse(numInput2, out cleanNum2)) { Console.Write("This is not valid input. Please enter an integer value: "); numInput2 = Console.ReadLine(); } // Ask the user to choose an operator. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 321 Console.WriteLine("Choose an operator from the following list:"); Console.WriteLine("\ta - Add"); Console.WriteLine("\ts - Subtract"); Console.WriteLine("\tm - Multiply"); Console.WriteLine("\td - Divide"); Console.Write("Your option? "); string op = Console.ReadLine(); try { result = Calculator.DoOperation(cleanNum1, cleanNum2, op); if (double.IsNaN(result)) { Console.WriteLine("This operation will result in a mathematical error.\n"); } else Console.WriteLine("Your result: {0:0.##}\n", result); } catch (Exception e) { Console.WriteLine("Oh no! An exception occurred trying to do the math.\n Details: " + e.Message); } Console.WriteLine("------------------------\n"); // Wait for the user to respond before closing. Console.Write("Press 'n' and Enter to close the app, or press any other key and Enter to continue: "); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 322 if (Console.ReadLine() == "n") endApp = true; Console.WriteLine("\n"); // Friendly linespacing. } return; } } } Command-line parameters COMMAND-LINE PARAMETERS A command line parameter can be used to enable or disable certain features of a game when the program begins. The most commonly used command line parameter for video games is -console. For many PC games, this command enables the console where additional cheats can be entered. In other games, the cheat console is available by default, so there is no need to edit command line parameters. Although entering command line parameters incorrectly can cause a game to crash, it will not corrupt the actual game files. How to Edit Shortcut Launch Parameters While this method can seem tedious at first, it's a lot safer than editing game files to enable cheats. If you don't see an icon for the game on your desktop, you must first create a shortcut for the game's EXE file. To add command line parameters to a shortcut: 1. Right-click the shortcut to the game on your desktop and select Properties. 2. Go to the Shortcut tab, then locate the Target field, which lists the exact location of the file within quotation marks. 3. In the Target text box, place the cursor after the last quotation mark, then add a blank space followed by the command line parameters. All command line parameters are preceded with a hyphen (-). 4. Select Apply, then select OK. 5. Double-click the shortcut to start the game with command line cheats enabled. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 323 To disable cheats, remove the command line parameter from the shortcut and restart the game. Examples of Command Line Parameter Shortcuts Here is an example of a shortcut target for Half-Life without any extra command line parameters: "C:\Program Files\Sierra\Half-Life\hl.exe" Here is the same shortcut for Half-Life with a command line parameter added to it: "C:\Program Files\Sierra\Half-Life\hl.exe" -console Add multiple command parameters one after another by leaving a space between them. For example: "C:\Program Files\Sierra\Half-Life\hl.exe" -dev -console Another way to add command line parameters is to launch the game from the command prompt. More Ways to Use Cheat Codes in PC Games While some games require you to edit command line parameters to activate cheats, other games require you to enter cheat codes at the title screen or in a designated menu. Other games require you to make changes to game files, which can cause serious problems if done incorrectly. Cheat guides typically include instructions for how cheats should be used. Windows services WINDOWS SERVICES Microsoft Windows services, formerly known as NT services, enable you to create long-running executable applications that run in their own Windows sessions. These services can be automatically started when the computer boots, can be paused and restarted, and do not show any user interface. These features make services ideal for use on a server or whenever you need longrunning functionality that does not interfere with other users who are working on the same computer. You can also run services in the security context of a specific user account that is different from the logged-on user or the default computer account. For more information about services and Windows sessions, see the Windows SDK documentation. You can easily create services by creating an application that is installed as a service. For example, suppose you want to monitor performance counter data and react to threshold values. You could write a Windows Service application that listens to the performance counter data, deploy the application, and begin collecting and analyzing data. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 324 You create your service as a Microsoft Visual Studio project, defining code within it that controls what commands can be sent to the service and what actions should be taken when those commands are received. Commands that can be sent to a service include starting, pausing, resuming, and stopping the service; you can also execute custom commands. After you create and build the application, you can install it by running the command-line utility Page | 325 InstallUtil.exe and passing the path to the service's executable file. You can then use the Services Control Manager to start, stop, pause, resume, and configure your service. You can also accomplish many of these same tasks in the Services node in Server Explorer or by using the ServiceController class. SERVICE APPLICATIONS VS. OTHER VISUAL STUDIO APPLICATIONS Service applications function differently from many other project types in several ways: • The compiled executable file that a service application project creates must be installed on the server before the project can function in a meaningful way. You cannot debug or run a service application by pressing F5 or F11; you cannot immediately run a service or step into its code. Instead, you must install and start your service, and then attach a debugger to the service's process. For more information, see How to: Debug Windows Service Applications. • Unlike some types of projects, you must create installation components for service applications. The installation components install and register the service on the server and create an entry for your service with the Windows Services Control Manager. For more information, see How to: Add Installers to Your Service Application. • The Main method for your service application must issue the Run command for the services your project contains. The Run method loads the services into the Services Control Manager on the appropriate server. If you use the Windows Services project template, this method is written for you automatically. Note that loading a service is not the same thing as starting the service. See "Service Lifetime" below for more information. • Windows Service applications run in a different window station than the interactive station of the logged-on user. A window station is a secure object that contains a Clipboard, a set of global atoms, and a group of desktop objects. Because the station of the Windows service is not an interactive station, dialog boxes raised from within a Windows service application will not be seen and may cause your program to stop responding. Similarly, error messages should be logged in the Windows event log rather than raised in the user interface. The Windows service classes supported by the .NET Framework do not support interaction with interactive stations, that is, the logged-on user. The .NET Framework also does not include classes that represent stations and desktops. If your Windows service must interact with other stations, you will need to access the unmanaged Windows API. For more information, see the Windows SDK documentation. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) The interaction of the Windows service with the user or other stations must be carefully designed to include scenarios such as there being no logged on user, or the user having an unexpected set of desktop objects. In some cases, it may be more appropriate to write a Windows application that runs under the control of the user. • Windows service applications run in their own security context and are started before the Page | 326 user logs into the Windows computer on which they are installed. You should plan carefully what user account to run the service within; a service running under the system account has more permissions and privileges than a user account. SERVICE LIFETIME A service goes through several internal states in its lifetime. First, the service is installed onto the system on which it will run. This process executes the installers for the service project and loads the service into the Services Control Manager for that computer. The Services Control Manager is the central utility provided by Windows to administer services. After the service has been loaded, it must be started. Starting the service allows it to begin functioning. You can start a service from the Services Control Manager, from Server Explorer, or from code by calling the Start method. The Start method passes processing to the application's OnStart method and processes any code you have defined there. A running service can exist in this state indefinitely until it is either stopped or paused or until the computer shuts down. A service can exist in one of three basic states: Running, Paused, or Stopped. The service can also report the state of a pending command: ContinuePending, PausePending, StartPending, or StopPending. These statuses indicate that a command has been issued, such as a command to pause a running service, but has not been carried out yet. You can query the Status to determine what state a service is in, or use the WaitForStatus to carry out an action when any of these states occurs. You can pause, stop, or resume a service from the Services Control Manager, from Server Explorer, or by calling methods in code. Each of these actions can call an associated procedure in the service (OnStop, OnPause, or OnContinue), in which you can define additional processing to be performed when the service changes state. TYPES OF SERVICES There are two types of services you can create in Visual Studio using the .NET Framework. Services that are the only service in a process are assigned the type Win32OwnProcess. Services that share a process with another service are assigned the type Win32ShareProcess. You can retrieve the service type by querying the ServiceType property. You might occasionally see other service types if you query existing services that were not created in Visual Studio. For more information on these, see the ServiceType. Services and the ServiceController Component COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) The ServiceController component is used to connect to an installed service and manipulate its state; using a ServiceController component, you can start and stop a service, pause and continue its functioning, and send custom commands to a service. However, you do not need to use a ServiceController component when you create a service application. In fact, in most cases your ServiceController component should exist in a separate application from the Windows service application that defines your service. Requirements • Services must be created in a Windows Service application project or another .NET Framework–enabled project that creates an .exe file when built and inherits from the Service Base class. Projects containing Windows services must have installation components for the project and its services. This can be easily accomplished from the Properties window. Creating a windows service CREATING A WINDOWS SERVICE Windows Services normally start when the OS boots and runs an application in the background. Windows Services executes applications in its own session. It either starts automatically or we can manually pause, stop, and restart it. You can find services in the following ways • Go to Control Panel select “Services” inside “Administrative Tools.” • Open Run window (Window + R), type in services.msc, and press enter. How to Create a Windows Service Step 1 Open Visual Studio, go to File > New and select Project. Now select a new project from the Dialog box and select “Window Service” and click on the OK button. Step 2 Go to Visual C# -> ”Windows Desktop” -> ”Windows Service,” give your project an appropriate name and then click OK Once you click OK, the below screen will appear, which is your service Step 3 Right-click on the blank area and select “Add Installer.” Adding Installers to the Service COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 327 Before you can run a Windows Service, you need to install the Installer, which registers it with the Service Control Manager. After Adding Installer, ProjectInstaller will add in your project and ProjectInstakker.cs file will be open. Don’t forget to save everything (by pressing ctrl + shift + s key) Page | 328 The Solution Explorer looks like this: Step 4 Right click on blank area and select “View Code” Step 5 Its has a Constructor, which contains the InitializeComponent method. The InitializeComponent method contains the logic which creates and initializes the user interface objects dragged on the form's surface and provides the Property Grid of Form Designer. Very important: Don't ever try to call any method before the call of InitializeComponent method. Step 6 Select the InitializeComponent method and press the F12 key to go the definition. Step 7 Now add the below line while installing the service: 1 this.serviceProcessInstaller1.Account = System.ServiceProcess.ServiceAccount.LocalSystem; You also can add a description and display the service name (optionally). 1 this.serviceInstaller1.Description = "My First Service demo"; 2 this.serviceInstaller1.DisplayName = "MyFirstService.Demo"; Step 8 In this step, we will implement a timer, and code to call a service at a given time. We will create a simple write in a text file. Service1.cs class 1 COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) using System; 2 using System.Collections.Generic; 3 Page | 329 using System.ComponentModel; 4 using System.Data; 5 using System.Diagnostics; 6 using System.IO; 7 using System.Linq; 8 using System.ServiceProcess; 9 using System.Text; 10 using System.Threading.Tasks; 11 using System.Timers; 12 13 namespace MyFirstService { 14 public partial class Service1: ServiceBase { 15 COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Timer timer = new Timer(); // name space(using System.Timers;) 16 public Service1() { 17 Page | 330 InitializeComponent(); 18 } 19 protected override void OnStart(string[] args) { 20 WriteToFile("Service is started at " + DateTime.Now); 21 timer.Elapsed += new ElapsedEventHandler(OnElapsedTime); 22 timer.Interval = 5000; //number in milisecinds 23 timer.Enabled = true; 24 } 25 protected override void OnStop() { 26 WriteToFile("Service is stopped at " + DateTime.Now); 27 } 28 private void OnElapsedTime(object source, ElapsedEventArgs e) { 29 COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) WriteToFile("Service is recall at " + DateTime.Now); 30 } 31 Page | 331 public void WriteToFile(string Message) { 32 string path = AppDomain.CurrentDomain.BaseDirectory + "\\Logs"; 33 if (!Directory.Exists(path)) { 34 Directory.CreateDirectory(path); 35 } 36 string filepath = AppDomain.CurrentDomain.BaseDirectory + "\\Logs\\ServiceLog_" + DateTime.Now.Date.ToShortDateString().Replace('/', '_') + ".txt"; 37 if (!File.Exists(filepath)) { 38 // Create a file to write to. 39 using(StreamWriter sw = File.CreateText(filepath)) { 40 sw.WriteLine(Message); 41 } 42 } else { 43 COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) using(StreamWriter sw = File.AppendText(filepath)) { 44 sw.WriteLine(Message); 45 Page | 332 } 46 } 47 } 48 } 49 } Code explanation - the above code will call a service every 5 seconds and create a folder if none exist and write our message. Step 9: Rebuild Your Application Right-click on your project or solution and select Rebuild. Step 10 Search “command Prompt” and run the program as an administrator: Step 11 Fire the below command in the command prompt and press Enter. cd C:\Windows\Microsoft.NET\Framework\v4.0.30319 Step 12 Now Go to your project source folder > bin > Debug and copy the full path of of the Windows Service.exe file Step 13 Open the command prompt and fire the below command and press enter. Syntax COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) InstallUtil.exe + Your copied path + \your service name + .exe Our Path InstallUtil.exe C:\Users\FaisalPathan\source\repos\MyFirstService\MyFirstService\bin\Debug\MyFirstService.exe Step 14 Open services by following the below steps: 1. Press Window key + R. 2. Type services.msc 3. Find your Service. Service Output A log folder will be created in your bin folder. If you want to uninstall the service, fire the below command. 1. Syntax InstallUtil.exe -u + Your copied path + \your service name + .exe 2. Our path InstallUtil.exe -u C:\Users\FaisalPathan\source\repos\MyFirstService\MyFirstService\bin\Debug\MyFirstService.exe Summary In this article, we learned how to create a Windows Service and install/uninstall it using the InstallUtil.exe from a command prompt. I hope that I have explained each step clearly and that it can be easily understood by all developers. You can leave feedback/comments/questions to this article. Please let me know if you like and understand this article and how I could improve it. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 333 UNIT 3 DATABASE CONCEPTS AND DESIGN The concept and uses of databases THE CONCEPT AND USES OF DATABASES DATA In simple words, data can be facts related to any object in consideration. For example, your name, age, height, weight, etc. are some data related to you. A picture, image, file, pdf, etc. can also be considered data. DATABASE A database is an organized collection of structured information, or data, typically stored electronically in a computer system. A database is usually controlled by a database management system (DBMS). Together, the data and the DBMS, along with the applications that are associated with them, are referred to as a database system, often shortened to just database. Data within the most common types of databases in operation today is typically modeled in rows and columns in a series of tables to make processing and data querying efficient. The data can then be easily accessed, managed, modified, updated, controlled, and organized. Most databases use structured query language (SQL) for writing and querying data. Example: An online telephone directory uses a database to store data of people, phone numbers, and other contact details. Your electricity service provider uses a database to manage billing, client-related issues, handle fault data, etc. Let us also consider Facebook. It needs to store, manipulate, and present data related to members, their friends, member activities, messages, advertisements, and a lot more. We can provide a countless number of examples for the usage of databases. EVOLUTION OF THE DATABASE Databases have evolved dramatically since their inception in the early 1960s. Navigational databases such as the hierarchical database (which relied on a tree-like model and allowed only a one-to-many relationship), and the network database (a more flexible model that allowed multiple relationships), were the original systems used to store and manipulate data. Although simple, these early systems were inflexible. In the 1980s, relational databases became popular, followed by object-oriented databases in the 1990s. More recently, NoSQL databases came about as a response to the growth of the internet and the need for faster speed and processing of unstructured data. Today, cloud databases and self-driving databases are breaking new ground when it comes to how data is collected, stored, managed, and utilized. TYPES OF DATABASES COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 334 Distributed databases: A distributed database consists of two or more files located in different sites. The database may be stored on multiple computers, located in the same physical location, or scattered over different networks. Relational databases: This type of database defines database relationships in the form of tables. Items in a relational database are organized as a set of tables with columns and rows. It is also called Relational DBMS, which is the most popular DBMS type in the market. Database example of the RDBMS system include MySQL, Oracle, and Microsoft SQL Server database. Object-oriented databases: This type of computers database supports the storage of all data types. The data is stored in the form of objects. The objects to be held in the database have attributes and methods that define what to do with the data. PostgreSQL is an example of an object-oriented relational DBMS. Centralized database: It is a centralized location, and users from different backgrounds can access this data. This type of computers databases stores application procedures that help users access the data even from a remote location. Open-source databases: This kind of database stored information related to operations. It is mainly used in the field of marketing, employee relations, customer service, of databases. Cloud databases: A cloud database is a database which is optimized or built for such a virtualized environment. A cloud database is a collection of data, either structured or unstructured, that resides on a private, public, or hybrid cloud computing platform. There are two types of cloud database models: traditional and database as a service (DBaaS). With DBaaS, administrative tasks and maintenance are performed by a service provider. There are so many advantages of a cloud database, some of which can pay for storage capacity and bandwidth. It also offers scalability ondemand, along with high availability. Data warehouses: A central repository for data, a data warehouse is a type of database specifically designed for fast query and analysis. Data Warehouse is to facilitate a single version of truth for a company for decision making and forecasting. A Data warehouse is an information system that contains historical and commutative data from single or multiple sources. Data Warehouse concept simplifies the reporting and analysis process of the organization. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 335 NoSQL databases: A NoSQL, or non- relational database, allows unstructured and semi structured data to be stored and manipulated (in contrast to a relational database, which defines how all data inserted into the database must be composed). NoSQL database is used for large sets of distributed data. There are a few big data performance problems that are effectively handled by relational databases. This type of computers database is very efficient in analyzing large-size unstructured data. Graph databases: A graph-oriented database uses graph theory to store, map, and query relationships. These kinds of computers databases are mostly used for analyzing interconnections. For example, an organization can use a graph database to mine data about customers from social media. OLTP databases: OLTP another database type which able to perform fast query processing and maintaining data integrity in multi-access environments. Personal database: A personal database is used to store data stored on personal computers that are smaller and easily manageable. The data is mostly used by the same department of the company and is accessed by a small group of people. Multimodal database: The multimodal database is a type of data processing platform that supports the combination of different types of database models into a single, integrated back end. This means they can accommodate various data types. Document/JSON database: In a document-oriented database, the data is kept in document collections, usually using the XML, JSON, BSON formats. One record can store as much data as you want, in any data type (or types) you prefer. Self-driving databases The newest and most groundbreaking type of database, self-driving databases (also known as autonomous databases) are cloud-based and use machine learning to automate database tuning, security, backups, updates, and other routine management tasks traditionally performed by database administrators Hierarchical: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 336 This type of DBMS employs the “parent-child” relationship of storing data. Its structure is like a tree with nodes representing records and branches representing fields. The windows registry used in Windows XP is a hierarchical database example. Network DBMS: This type of DBMS supports many-to-many relations. It usually results in complex database structures. RDM Server is an example of database management system that implements the network model. COMPONENTS OF DATABASE Database Components There are five main components of a database: Hardware: The hardware consists of physical, electronic devices like computers, I/O devices, storage devices, etc. This offers the interface between computers and real-world systems. Software: This is a set of programs used to manage and control the overall database. This includes the database software itself, the Operating System, the network software used to share the data among users, and the application programs for accessing data in the database. Data: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 337 Data is a raw and unorganized fact that is required to be processed to make it meaningful. Data can be simple at the same time unorganized unless it is organized. Generally, data comprises facts, observations, perceptions, numbers, characters, symbols, images, etc. Procedure: Procedure are a set of instructions and rules that help you to use the DBMS. It is designing and running the database using documented methods, which allows you to guide the users who operate and manage it. Database Access Language: Database Access language is used to access the data to and from the database, enter new data, update already existing data, or retrieve required data from DBMS. The user writes some specific commands in a database access language and submits these to the database. DATABASE SOFTWARE Database software is used to create, edit, and maintain database files and records, enabling easier file and record creation, data entry, data editing, updating, and reporting. The software also handles data storage, backup and reporting, multi-access control, and security. Strong database security is especially important today, as data theft becomes more frequent. Database software is sometimes also referred to as a “database management system” (DBMS). Database software makes data management simpler by enabling users to store data in a structured form and then access it. It typically has a graphical interface to help create and manage the data and, in some cases, users can construct their own databases by using database software. DATABASE CHALLENGES Today’s large enterprise databases often support very complex queries and are expected to deliver nearly instant responses to those queries. As a result, database administrators are constantly called upon to employ a wide variety of methods to help improve performance. Some common challenges that they face include: • Absorbing significant increases in data volume. The explosion of data coming in from sensors, connected machines, and dozens of other sources keeps database administrators scrambling to manage and organize their companies’ data efficiently. • Ensuring data security. Data breaches are happening everywhere these days, and hackers are getting more inventive. It’s more important than ever to ensure that data is secure but also easily accessible to users. • Keeping up with demand. In today’s fast-moving business environment, companies need real-time access to their data to support timely decision-making and to take advantage of new opportunities. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 338 • Managing and maintaining the database and infrastructure. Database administrators must continually watch the database for problems and perform preventative maintenance, as well as apply software upgrades and patches. As databases become more complex and data volumes grow, companies are faced with the expense of hiring additional talent to monitor and tune their databases. • Removing limits on scalability. A business needs to grow if it’s going to survive, and its data management must grow along with it. But it’s very difficult for database administrators to predict how much capacity the company will need, particularly with onpremises databases. • Ensuring data residency, data sovereignty, or latency requirements. Some organizations have use cases that are better suited to run on-premises. In those cases, engineered systems that are pre-configured and pre-optimized for running the database are ideal. Customers achieve higher availability, greater performance and up to 40% lower cost with Oracle Exadata, according to Wikibon’s recent analysis (PDF). Addressing all of these challenges can be time-consuming and can prevent database administrators from performing more strategic functions. What’s the difference between a database and a spreadsheet? Databases and spreadsheets (such as Microsoft Excel) are both convenient ways to store information. The primary differences between the two are: • How the data is stored and manipulated? • Who can access the data? • How much data can be stored? Spreadsheets were originally designed for one user, and their characteristics reflect that. They’re great for a single user or small number of users who don’t need to do a lot of incredibly complicated data manipulation. Databases, on the other hand, are designed to hold much larger collections of organized information—massive amounts, sometimes. Databases allow multiple users at the same time to quickly and securely access and query the data using highly complex logic and language. FILE BASED APPROACH VS. DATABASE APPROACH FILE-BASED APPROACH The term 'file-based approach' refers to the situation where data is stored in one or more separate computer files defined and managed by different application programs. Typically, for example, the details of customers may be stored in one file, orders in another, etc. Computer programs access the stored files to perform the various tasks required by the business. Each program, or sometimes a related set of programs, is called a computer application. For example, all of the programs associated with processing customers' orders are referred to as the order processing COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 339 application. The file-based approach might have application programs that deal with purchase orders, invoices, sales and marketing, suppliers, customers, employees, and so on. One way to keep information on a computer is to store it in permanent files. A company system has a number of application programs; each of them is designed to manipulate data files. These application programs have been written at the request of the users in the organization. New applications are added to the system as the need arises. The system just described is called the file-based system. Consider a traditional banking system that uses the file-based system to manage the organization’s data shown in Figure 1.1. As we can see, there are different departments in the bank. Each has its own applications that manage and manipulate different data files. For banking systems, the programs may be used to debit or credit an account, find the balance of an account, add a new mortgage loan and generate monthly statements. Limitations • Data duplication: Each program stores its own separate files. If the same data is to be accessed by different programs, then each program must store its own copy of the same data. • Data inconsistency: If the data is kept in different files, there could be problems when an item of data needs updating, as it will need to be updated in all the relevant files; if this is not done, the data will be inconsistent, and this could lead to errors. • Difficult to implement data security: Data is stored in different files by different application programs. This makes it difficult and expensive to implement organisationwide security procedures on the data. The following diagram shows how different applications will each have their own copy of the files they need in order to carry out the activities for which they are responsible: Figure 1.1 The shared file approach COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 340 One approach to solving the problem of each application having its own set of files is to share files between different applications. This will alleviate the problem of duplication and inconsistent data between different applications, and is illustrated in the diagram below: Page | 341 Figure 1.2 DISADVANTAGES OF THE FILE-BASED APPROACH Using the file-based system to keep organizational information has a number of disadvantages. Listed below are five examples. 1. Data redundancy Often, within an organization, files and applications are created by different programmers from various departments over long periods of time. This can lead to data redundancy, a situation that occurs in a database when a field needs to be updated in more than one table. This practice can lead to several problems such as: • Inconsistency in data format • The same information being kept in several different places (files) • Data inconsistency, a situation where various copies of the same data are conflicting, wastes storage space and duplicates effort 2. Data isolation Data isolation is a property that determines when and how changes made by one operation become visible to other concurrent users and systems. This issue occurs in a concurrency situation. This is a problem because: • It is difficult for new applications to retrieve the appropriate data, which might be stored in various files. 3. Integrity problems Problems with data integrity is another disadvantage of using a file-based system. It refers to the maintenance and assurance that the data in a database are correct and consistent. Factors to consider when addressing this issue are: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) • Data values must satisfy certain consistency constraints that are specified in the application programs. • It is difficult to make changes to the application programs in order to enforce new constraints. 4. Security problems Security can be a problem with a file-based approach because: • There are constraints regarding accessing privileges. • Application requirements are added to the system in an ad-hoc manner so it is difficult to enforce constraints. 5. Concurrency access Concurrency is the ability of the database to allow multiple users access to the same record without adversely affecting transaction processing. A file-based system must manage, or prevent, concurrency by the application programs. Typically, in a file-based system, when an application opens a file, that file is locked. This means that no one else has access to the file at the same time. In database systems, concurrency is managed thus allowing multiple users access to the same record. This is an important difference between database and file-based systems. DATABASE APPROACH The difficulties that arise from using the file-based system have prompted the development of a new approach in managing large amounts of organizational information called the database approach. Databases and database technology play an important role in most areas where computers are used, including business, education and medicine. To understand the fundamentals of database systems, we will start by introducing some basic concepts in this area. Role of databases in business Everybody uses a database in some way, even if it is just to store information about their friends and family. That data might be written down or stored in a computer by using a word-processing program or it could be saved in a spreadsheet. However, the best way to store data is by using database management software. This is a powerful software tool that allows you to store, manipulate and retrieve data in a variety of different ways. Most companies keep track of customer information by storing it in a database. This data may include customers, employees, products, orders or anything else that assists the business with its operations. The database approach is an improvement on the shared file solution as the use of a database management system (DBMS) provides facilities for querying, data security and integrity, and COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 342 allows simultaneous access to data by a number of different users. At this point we should explain some important terminology: • Database: A database is a collection of related data. • Database management system: The term 'database management system', often abbreviated to DBMS, refers to a software system used to create and manage databases. The software of such systems is complex, consisting of a number of different components, which are described later in this chapter. The term database system is usually an alternative term for database management system. • System catalogue/Data dictionary: The description of the data in the database management system. • Database application: Database application refers to a program, or related set of programs, which use the database management system to perform the computer-related tasks of a particular business function, such as order processing. One of the benefits of the database approach is that the problem of physical data dependence is resolved; this means that the underlying structure of a data file can be changed without the application programs needing amendment. This is achieved by a hierarchy of levels of data specification. Each such specification of data in a database system is called a schema. The different levels of schema provided in database systems are described below. Further details of what is included within each specific schema are discussed later in the chapter. The Systems Planning and Requirements Committee of the American National Standards Institute encapsulated the concept of schema in its three-level database architecture model, known as the ANSI/SPARC architecture, which is shown in the diagram below: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 343 Page | 344 Figure 1.3 ANSI/SPARC three-level architecture ANSI = American National Standards Institute ANSI/X3 = Committee on Computers and Information Processing SPARC = Standards Planning and Requirements Committee The ANSI/SPARC model is a three-level database architecture with a hierarchy of levels, from the users and their applications at the top, down to the physical storage of data at the bottom. The characteristics of each level, represented by a schema, are now described. The external schema The external schemas describe the database as it is seen by the user, and the user applications. The external schema maps onto the conceptual schema, which is described below. There may be many external schemas, each reflecting a simplified model of the world, as seen by particular applications. External schemas may be modified, or new ones created, without the need to make alterations to the physical storage of data. The interface between the external schema and the conceptual schema can be amended to accommodate any such changes. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) The external schema allows the application programs to see as much of the data as they require, while excluding other items that are not relevant to that application. In this way, the external schema provides a view of the data that corresponds to the nature of each task. The external schema is more than a subset of the conceptual schema. While items in the external schema must be derivable from the conceptual schema, this could be a complicated process, Page | 345 involving computation and other activities. The conceptual schema The conceptual schema describes the universe of interest to the users of the database system. For a company, for example, it would provide a description of all of the data required to be stored in a database system. From this organisation-wide description of the data, external schemas can be derived to provide the data for specific users or to support particular tasks. At the level of the conceptual schema we are concerned with the data itself, rather than storage or the way data is physically accessed on disk. The definition of storage and access details is the preserve of the internal schema. The internal schema A database will have only one internal schema, which contains definitions of the way in which data is physically stored. The interface between the internal schema and the conceptual schema identifies how an element in the conceptual schema is stored, and how it may be accessed. If the internal schema is changed, this will need to be addressed in the interface between the internal and the conceptual schemas, but the conceptual and external schemas will not need to change. This means that changes in physical storage devices such as disks, and changes in the way files are organised on storage devices, are transparent to users and application programs. In distinguishing between 'logical' and 'physical' views of a system, it should be noted that the difference could depend on the nature of the user. While 'logical' describes the user angle, and 'physical' relates to the computer view, database designers may regard relations (for staff records) as logical and the database itself as physical. This may contrast with the perspective of a systems programmer, who may consider data files as logical in concept, but their implementation on magnetic disks in cylinders, tracks and sectors as physical. Physical data independence In a database environment, if there is a requirement to change the structure of a particular file of data held on disk, this will be recorded in the internal schema. The interface between the internal schema and the conceptual schema will be amended to reflect this, but there will be no need to change the external schema. This means that any such change of physical data storage is not transparent to users and application programs. This approach removes the problem of physical data dependence. Logical data independence COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Any changes to the conceptual schema can be isolated from the external schema and the internal schema; such changes will be reflected in the interface between the conceptual schema and the other levels. This achieves logical data independence. What this means, effectively, is that changes can be made at the conceptual level, where the overall model of an organisation's data is specified, and these changes can be made independently of both the physical storage level, and Page | 346 the external level seen by individual users. The changes are handled by the interfaces between the conceptual, middle layer, and the physical and external layers. THE BENEFITS OF THE DATABASE APPROACH • Ease of application development: The programmer is no longer burdened with designing, building and maintaining master files. • Minimal data redundancy: All data files are integrated into a composite data structure. In practice, not all redundancy is eliminated, but at least the redundancy is controlled. Thus inconsistency is reduced. • Enforcement of standards: The database administrator can define standards for names, etc. • Data can be shared. New applications can use existing data definitions. • Physical data independence: Data descriptions are independent of the application programs. This makes program development and maintenance an easier task. Data is stored independently of the program that uses it. • Logical data independence: Data can be viewed in different ways by different users. • Better modelling of real-world data: Databases are based on semantically rich data models that allow the accurate representation of real-world information. • Uniform security and integrity controls: Security control ensures that applications can only access the data they are required to access. Integrity control ensures that the database represents what it purports to represent. • Economy of scale: Concentration of processing, control personal and technical expertise. DISAVANTAGES OF THE DATABASE APPROACH • New specialized personnel: Need to hire or train new personnel e.g. database administrators and application programmers. • Need for explicit backup. • Organizational conflict: Different departments have different information needs and data representation. • Large size: Often needs alarmingly large amounts of processing power. • Expensive: Software and hardware expenses. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) • High impact of failure: Concentration of processing and resources makes an organization vulnerable if the system fails for any length of time. Relational database concepts RELATIONAL DATABASE CONCEPTS A relational database organizes data into tables which can be linked—or related—based on data Page | 347 common to each. This capability enables you to retrieve an entirely new table from data in one or more tables with a single query. It also allows you and your business to better understand the relationships among all available data and gain new insights for making better decisions or identifying new opportunities. For example, imagine your company maintains a customer table that contains company data about each customer account and one or more transaction tables that contain data describing individual transactions. The columns (or fields) for the customer table might be Customer ID, Company Name, Company Address, etc.; the columns for a transaction table might be Transaction Date, Customer ID, Transaction Amount, Payment Method, etc. The tables can be related based on the common Customer ID field. You can, therefore, query the table to produce valuable reports, such as a consolidated customer statement. Report generators take these queries and run them on demand to create formal reports. Many of the documents businesses run to track inventory, sales, finance, or even perform financial projections come from a relational database operating behind the scenes. RDBMS stands for Relational Database Management System. RDBMS is the basis for SQL, and for all modern database systems like MS SQL Server, IBM DB2, Oracle, MySQL, and Microsoft Access. A Relational database management system (RDBMS) is a database management system (DBMS) that is based on the relational model as introduced by E. F. Codd. What is a table? The data in an RDBMS is stored in database objects which are called as tables. This table is basically a collection of related data entries and it consists of numerous columns and rows. Remember, a table is the most common and simplest form of data storage in a relational database. The following program is an example of a CUSTOMERS table − +----+----------+-----+-----------+----------+ | ID | NAME | AGE | ADDRESS | SALARY | +----+----------+-----+-----------+----------+ | 1 | Ramesh | 32 | Ahmedabad | 2000.00 | | 2 | Khilan | 25 | Delhi | 1500.00 | COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) | 3 | kaushik | 23 | Kota | 4 | Chaitali | 25 | Mumbai | 2000.00 | | 6500.00 | | 5 | Hardik | 27 | Bhopal | 8500.00 | | 6 | Komal | 22 | MP | 4500.00 | | 7 | Muffy | 24 | Indore | 10000.00 | +----+----------+-----+-----------+----------+ What is a field? Every table is broken up into smaller entities called fields. The fields in the CUSTOMERS table consist of ID, NAME, AGE, ADDRESS and SALARY. A field is a column in a table that is designed to maintain specific information about every record in the table. What is a Record or a Row? A record is also called as a row of data is each individual entry that exists in a table. For example, there are 7 records in the above CUSTOMERS table. Following is a single row of data or record in the CUSTOMERS table − +----+----------+-----+-----------+----------+ | 1 | Ramesh | 32 | Ahmedabad | 2000.00 | +----+----------+-----+-----------+----------+ A record is a horizontal entity in a table. What is a column? A column is a vertical entity in a table that contains all information associated with a specific field in a table. For example, a column in the CUSTOMERS table is ADDRESS, which represents location description and would be as shown below − +-----------+ | ADDRESS | +-----------+ | Ahmedabad | | Delhi | | Kota | COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 348 | Mumbai | | Bhopal | | MP | | Indore | +----+------+ What is a NULL value? A NULL value in a table is a value in a field that appears to be blank, which means a field with a NULL value is a field with no value. It is very important to understand that a NULL value is different than a zero value or a field that contains spaces. A field with a NULL value is the one that has been left blank during a record creation. SQL Constraints Constraints are the rules enforced on data columns on a table. These are used to limit the type of data that can go into a table. This ensures the accuracy and reliability of the data in the database. Constraints can either be column level or table level. Column level constraints are applied only to one column whereas, table level constraints are applied to the entire table. Following are some of the most commonly used constraints available in SQL − • NOT NULL Constraint − Ensures that a column cannot have a NULL value. • DEFAULT Constraint − Provides a default value for a column when none is specified. • UNIQUE Constraint − Ensures that all the values in a column are different. • PRIMARY Key − Uniquely identifies each row/record in a database table. • FOREIGN Key − Uniquely identifies a row/record in any another database table. • CHECK Constraint − The CHECK constraint ensures that all values in a column satisfy certain conditions. • INDEX − Used to create and retrieve data from the database very quickly. Data Integrity The following categories of data integrity exist with each RDBMS − • Entity Integrity − There are no duplicate rows in a table. • Domain Integrity − Enforces valid entries for a given column by restricting the type, the format, or the range of values. • Referential integrity − Rows cannot be deleted, which are used by other records. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 349 • User-Defined Integrity − Enforces some specific business rules that do not fall into entity, domain or referential integrity. Database Normalization Database normalization is the process of efficiently organizing data in a database. There are two reasons of this normalization process − • Eliminating redundant data, for example, storing the same data in more than one table. • Ensuring data dependencies make sense. Both these reasons are worthy goals as they reduce the amount of space a database consumes and ensures that data is logically stored. Normalization consists of a series of guidelines that help guide you in creating a good database structure. Normalization guidelines are divided into normal forms; think of a form as the format or the way a database structure is laid out. The aim of normal forms is to organize the database structure, so that it complies with the rules of first normal form, then second normal form and finally the third normal form. It is your choice to take it further and go to the fourth normal form, fifth normal form and so on, but in general, the third normal form is more than enough. • First Normal Form (1NF) • Second Normal Form (2NF) • Third Normal Form (3NF) EXAMPLES OF RELATIONAL DATABASES Many database products implement the relational database model. They either use a SQL database for processing or can at least process SQL statements for requests and database updates. These databases range from small, desktop systems to massive cloud-based systems. They can be either open source and internally supported, open source with commercial support, or commercial closed-source systems. Here are a few of the more popular ones: MySQL MySQL is a common and easy to start a low-memory/disk/CPU database. It supports all the basic SQL commands, along with transactions and Atomicity, Consistency, Isolation, Durability (ACID) performance. MySQL is the most common database integrated with WordPress sites. PostgreSQL PostgreSQL is also open source. It provides enterprise features such as security, scalability, and support for more automation through a command-line interface, as well as direct access over the web. PostgreSQL supports stored procedures, which is a more complex programming language built on top of SQL. Teams can use stored procedures to do data extraction, transform, and load COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 350 between systems. Examples of this use case include claims processing for insurance processing and order processing for complex orders. Postgres also works with qGIS (link resides outside IBM) or Geo Server (link resides outside IBM) to store and save global information. For a closer look, see also "Database Deep Dives: PostgreSQL." Db2 Db2 is a commercially supported relational database from IBM that has both a cloud-hosted version and an on-premises version. RELATIONAL VS. NOSQL NoSQL databases provide ways of storing, searching and retrieving data other than in tables with relationships. Here are a few of the key distinctions: Key-value pairs The most popular form of NoSQL database is a simple key-value pair. Key-value pairs place all the data in a single table. The key is a unique element. For employees or customers, the key might be an email address. For orders, it would be the order number. As long as every key is unique, a key-value pair can store all the relations in one "table." Availability over consistency When computers run over a network, they invariably need to decide to prioritize consistent results (where every answer is always the same) or high uptime, called "availability." This is called the "CAP Theory," which stands for Consistency, Availability, or Partition Tolerance. Relational databases ensure the information is always in-sync and consistent. Some NoSQL databases, like Redis, prefer to always provide a response. That means the information you receive from a query may be incorrect by a few seconds—perhaps up to half a minute. On social media sites, this means seeing an old profile picture when the newest one is only a few moments old. The alternative could be a timeout or error. On the other hand, in banking and financial transactions, an error and resubmit may be better than old, incorrect information. Flexible schemas While relational databases have a predefined set of rows and columns, NoSQL databases are structured more like a document. If you know where the information is in the document, you can retrieve it. If the material is still in the document, you can add other, structured information, without having to change the rules. If done correctly, the original queries will still work, making it easier to extend the database without formal updates. Other NoSQL database formats include document story, graph, and object databases. A broader term for NoSQL databases is non-relational. RELATIONAL VS. NON-RELATIONAL DATABASES Some examples of specific non-relational databases include the following: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 351 Redis Redis is a common NoSQL database, frequently used for the sort of data storage we discussed earlier. By doing just one lookup and no joins or relations, then moving processing to the web browser, Redis provides a rapid response. Response time can be critical for highly competitive modern websites. JanusGraph JanusGraph is a graph database designed to store and process queries for large graphs. These large graphs contain hundreds of billions of edges and vertices, stored in a multi-machine cluster. JanusGraph can support thousands of simultaneous queries and scale up with new hardware. The kind of data JanusGraph stores might be appropriate for animation or aerodynamic modeling. MongoDB MongoDB is a document database that stores records as loosely structured documents. That might be perfect for storing web pages as documents, for an e-Commerce product catalog, or social network applications. Like Redis, MongoDB differs from relational models in that it does not strive for ACID compliance. See also, "Database Deep Dives: MongoDB." etcd etcd is another key/value store, typically used for configuration data for distributed systems. The common etcd use case is cloud-based servers that scale up with demand and need a single database for configuration information. RabbitMQ RabbitMQ is an open source messaging queue. A message is typically some amount of text, with the structure defined by the client. Instead of records with a permanent shelf life, RabbitMQ allows one system to push messages into the queue so other applications can then pull messages when they want to. That asynchronous push/pull enables distributed applications with message passing. Elastic search Elasticsearch is a full-text search engine that interfaces through web APIs. That means the primary value is getting results back. An entire website can store itself in Elasticsearch. Look up the key-value pair, and you get the text of the website. The real power of Elasticsearch is the search enabling the website to add an accurate, fast search button. Elasticsearch can quickly and powerfully search for any large text structure. DIFFERENCES BETWEEN RELATIONAL DATABASES, NON-RELATIONAL DATABASES AND NOSQL COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 352 The most important difference between relational database systems and non-relational database systems is that relational databases are normalized. That is, they store data in a tabular form, arranged in a table with rows and columns. A non-relational database stores data as files. Other differences include the following: • Use of primary keys. Relational database tables each have a primary key identifier. In a non-relational database, data is normally stored in hierarchical or navigational form, without the use of primary keys. • Data values relationships. Since data in a relational database is stored in tables, the relationship between these data values is stored as well. Since a non-relational database stores data as files, there is no relationship between the data values. • Integrity constraints. In a relational database, the integrity constraints are any constraint that ensures database integrity. They are defined for the purpose of atomicity, consistency, isolation and durability, or ACID. Non-relational databases do not use integrity constraints. • Structured vs. unstructured data. Relational databases work well for structured data that conforms to a predefined data model and doesn't change much. Non-relational databases are better for unstructured data, which doesn't conform to a predefined data model and can't be stored in an RDBMS. Examples of unstructured data include text, emails, photos, videos and web pages. HOW TO CREATE A RELATIONAL DATABASE? A relational database needs two things to run—the database software itself and the Data Definition Language (DDL) code to create it. To support a local installation, administrators need to look into all possibilities. For example, if the underlying operating system the database runs on needs an update, that could take the server down for hours. For high availability, the database will need to be replicated, with a copy staying up while the parent is down. Local databases need to consider how to scale with multiple users, how to take backups, and how to restore them. The alternative is to run the databases in the cloud. With databases in the cloud, the database is automatically configured for high availability, meaning that your data replicates on multiple members, and each member sits on separate availability zones. If an entire data center goes down, the database stays up. Data replicates across zones, so you can maintain all the data and continue operations in the event of an outage. Also, the vendor will manage security improvements and operating system and database version upgrades. Users flock to cloud-managed databases for out-of-the-box enterprise security, high availability, online scaling, and automatic backups. Relational databases and IBM Cloud IBM supports cloud-hosted versions of a number of relational databases. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 353 • IBM Db2 on Cloud is a premier commercial relational database that is built for robust performance, providing a high-availability option with a 99.99 percent uptime SLA. • IBM Cloud Databases for PostgreSQL provides enterprise-ready, fully managed PostgreSQL, built with native integration into the IBM Cloud. • • IBM Cloud Hyper Protect DBaaS for PostgreSQL is the next evolution level on how data Page | 354 is stored in a highly secured enterprise cloud service ideally suited for workloads with sensitive data IBM Data Management Platform for EDB Postgres Enterprise and Standard is an integrated, open source-based PostgreSQL platform available in a one-stop experience that includes procurement, deployment, use, management and support. ADVANTAGES OF RELATIONAL DATABASES The key advantages of relational databases include the following: • Categorizing data. Database administrators can easily categorize and store data in a relational database that can then be queried and filtered to extract information for reports. Relational databases are also easy to extend and aren't reliant on physical organization. After the original database creation, a new data category can be added without having to modify the existing applications. • Accuracy. Data is stored just once, eliminating data deduplication in storage procedures. • Ease of use. Complex queries are easy for users to carry out with SQL, the main query language used with relational databases. • Collaboration. Multiple users can access the same database. • Security. Direct access to data in tables within an RDBMS can be limited to specific users. DISADVANTAGES OF RELATIONAL DATABASES The disadvantages of relational databases include the following: • Structure. Relational databases require a lot of structure and a certain level of planning because columns must be defined and data needs to fit correctly into somewhat rigid categories. The structure is good in some situations, but it creates issues related to the other drawbacks, such as maintenance and lack of flexibility and scalability. • Maintenance issues. Developers and other personnel responsible for the database must spend time managing and optimizing the database as data gets added to it. • Inflexibility. Relational databases are not ideal for handling large quantities of unstructured data. Data that is largely qualitative, not easily defined or dynamic is not optimal for relational databases, because as the data changes or evolves, the schema must evolve with it, which takes time. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) • Lack of scalability. Relational databases do not horizontally scale well across physical storage structures with multiple servers. It is difficult to handle relational databases across multiple servers because as a data set gets larger and more distributed, the structure is disrupted, and the use of multiple servers has effects on performance -- such as application response times -- and availability. Relational database design RELATIONAL DATABASE DESIGN This section introduces the fundamental principles of relational database design. A thorough database design supports an effective development process and is critical to successful database functionality and performance. The Demodata sample database is provided with installation and is frequently used in the documentation to illustrate database concepts and techniques. STAGES OF DESIGN Once you understand the basic structure of a relational database, you can begin the database design process. Designing a database is a process that involves developing and refining a database structure based on the requirements of your business. Database design includes the following three stages: 1. Conceptual Database Design 2. Logical Database Design 3. Physical Database Design CONCEPTUAL DESIGN The first step in the database design cycle is to define the data requirements for your business. Answering these types of questions helps you define the conceptual design: • What types of information does my business currently use? • What types of information does my business need? • What kind of information do I want from this system? • What are the assumptions on which my business runs? • What are the restrictions of my business? • What kind of reports do I need to generate? • What will I do with this information? • What kind of security does this system require? • What kinds of information are likely to expand? Identifying the goals of your business and gathering information from the different sources who will use the database is an essential process. With this information you can effectively define your tables and columns. LOGICAL DESIGN COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 355 Logical database design helps you further define and assess your business’ information requirements. Logical database design involves describing the information you need to track and the relationships among those pieces of information. Once you create a logical design, you can verify with the users of the database that the design is complete and accurate. They can determine if the design contains all of the information that must Page | 356 be tracked and that it reflects the relationships necessary to comply with the rules of your business. Creating a logical database design includes the following steps:  Define the tables you need based on the information your business requires (as determined in the conceptual design).  Determine the relationships between the tables. (See the section Table Relationships for more information.)  Determine the contents (columns) of each table.  Normalize the tables to at least the third normal form. (See the section Normalization for more information.)  Determine the primary keys. (See the section Keys for more information.)  Determine the values for each column. Table Relationships In a relational database, tables relate to one another by sharing a common column. This column, existing in two or more tables, allows you to join the tables. There are three types of table relationships: one-to-one, one-to-many, and many-to-many. A one-to-one relationship exists when each row in one table has only one related row in a second table. For example, a university may decide to assign one faculty member to one room. Thus, one room can only have one instructor assigned to it at a given time. The university may also decide that a department can only have one Dean. Thus, only one individual can be the head of a department. A one-to-many relationship exists when each row in one table has many related rows in another table. For example, one instructor can teach many classes. A many-to-many relationship exists when a row in one table has many related rows in a second table. Likewise, those related rows have many rows in the first table. A student can enroll in many courses, and courses can contain many students. Normalization Normalization is a process that reduces redundancy and increases stability in your database. Normalization involves determining in which table a particular piece of data belongs and its relationship to other data. Your database design results in a data-driven, rather than process or application-driven, design which provides a more stable database implementation. When you normalize your database, you eliminate the following columns: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) • Columns that contain more than one non-atomic value. • Columns that duplicate or repeat. • Columns that do not describe the table. • Columns that contain redundant data. • Columns that can be derived from other columns. First Normal Form Columns in the first normal form have the following characteristics: • They contain only one atomic value. • They do not repeat. The first rule of normalization is that you must remove duplicate columns or columns that contain more than one value to a new table. Tables normalized to the first normal form have several advantages. For example, in the Billing table of the sample database, first normal form does the following: Allows you to create any number of transactions for each student without having to add new columns. • Allows you to query and sort data for transactions quickly because you search only one column (transaction number). • Uses disk space more efficiently because no empty columns are stored. Second Normal Form • A table is in the second normal form when it is in the first normal form and only contains columns that provide information about the key of the table. In order to enforce the second rule of normalization, you must move those columns that do not depend on the primary key of the current table to a new table. A table violates second normal form if it contains redundant data. This may result in inconsistent data which causes your database to lack integrity. For example, if a student changes her address, you must then update all existing rows to reflect the new address. Any rows with the old address result in inconsistent data. To resolve these differences, identify data that remains the same when you add a transaction. Columns like Student Name or Street do not pertain to the transaction and do not depend on the primary key, Student ID. Therefore, store this information in the Student table, not in the transaction table. Tables normalized to the second normal form also have several advantages. For example, in the Billing table of the sample database, second normal form allows you to do the following: • Update student information in just one row. • Delete student transactions without eliminating necessary student information. • Use disk space more efficiently since no repeating or redundant data is stored. Third Normal Form COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 357 A table is in the third normal form when it contains only independent columns. The third rule of normalization is that you must remove columns that can be derived from existing columns. For example, for a student, you do not have to include an Age column if you already have a Date of Birth column, because you can calculate age from a date of birth. A table that is in third normal form contains only the necessary columns, so it uses disk space more efficiently since no unnecessary data is stored. In summary, the rules for the first, second, and third normal forms state that each column value must be a fact about the primary key in its entirety, and nothing else. Keys An ODBC key is a column or group of columns on which a table’s referential integrity (RI) constraints are defined. In other words, a key or combination of keys acts as an identifier for the data in a row. For more information about referential integrity and keys, refer to Advanced Operations Guide. PHYSICAL DESIGN The physical database design is a refinement of the logical design; it maps the logical design to a relational database management system. In this phase, you examine how the user accesses the database. This step of the database design cycle involves determining the following types of information: • • • • Data you will commonly use. Columns requiring indexes for data access. Areas needing flexibility or room for growth. Whether denormalizing the database will improve performance. (To denormalize your database, you reintroduce redundancy to meet performance.) For more information, see Normalization. Data normalization DATA NORMALIZATION Normalization is the process of organizing data in a database. This includes creating tables and establishing relationships between those tables according to rules designed both to protect the data and to make the database more flexible by eliminating redundancy and inconsistent dependency. Redundant data wastes disk space and creates maintenance problems. If data that exists in more than one place must be changed, the data must be changed in exactly the same way in all locations. A customer address change is much easier to implement if that data is stored only in the Customers table and nowhere else in the database. What is an "inconsistent dependency"? While it is intuitive for a user to look in the Customers table for the address of a particular customer, it may not make sense to look there for the salary COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 358 of the employee who calls on that customer. The employee's salary is related to, or dependent on, the employee and thus should be moved to the Employees table. Inconsistent dependencies can make data difficult to access because the path to find the data may be missing or broken. There are a few rules for database normalization. Each rule is called a "normal form." If the first rule is observed, the database is said to be in "first normal form." If the first three rules are observed, the database is considered to be in "third normal form." Although other levels of normalization are possible, third normal form is considered the highest level necessary for most applications. As with many formal rules and specifications, real world scenarios do not always allow for perfect compliance. In general, normalization requires additional tables and some customers find this cumbersome. If you decide to violate one of the first three rules of normalization, make sure that your application anticipates any problems that could occur, such as redundant data and inconsistent dependencies. DATABASE NORMAL FORMS Here is a list of Normal Forms in SQL: • 1NF (First Normal Form) • 2NF (Second Normal Form) • 3NF (Third Normal Form) • BCNF (Boyce-Codd Normal Form) • 4NF (Fourth Normal Form) • 5NF (Fifth Normal Form) • 6NF (Sixth Normal Form) The Theory of Data Normalization in MySQL server is still being developed further. For example, there are discussions even on 6th Normal Form. However, in most practical applications, normalization achieves its best in 3rd Normal Form. The evolution of Normalization in SQL theories is illustrated below- Normal Forms Database Database Normalization With Examples Database Normalization Example can be easily understood with the help of a case study. Assume, a video library maintains a database of movies rented out. Without any normalization in database, all information is stored in one table as shown below. Let’s understand Normalization database with normalization example with solution: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 359 Page | 360 S Here you see Movies Rented column has multiple values. Now let’s move into 1st Normal Forms: 1NF (First Normal Form) Rules • Each table cell should contain a single value. • Each record needs to be unique. The above table in 1NF1NF Example Example of 1NF in DBMS Before we proceed let’s understand a few things — What is a KEY in SQL? A KEY in SQL is a value used to identify records in a table uniquely. An SQL KEY is a single column or combination of multiple columns used to uniquely identify rows or tuples in the table. SQL Key is used to identify duplicate information, and it also helps establish a relationship between multiple tables in the database. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Note: Columns in a table that are NOT used to identify a record uniquely are called non-key columns. What is a Primary Key? Page | 361 Primary Key in DBMS A primary is a single column value used to identify a database record uniquely. It has following attributes • A primary key cannot be NULL • A primary key value must be unique • The primary key values should rarely be changed • The primary key must be given a value when a new record is inserted. What is Composite Key? A composite key is a primary key composed of multiple columns used to identify a record uniquely In our database, we have two people with the same name Robert Phil, but they live in different places. Composite key in Database Hence, we require both Full Name and Address to identify a record uniquely. That is a composite key. Let’s move into second normal form 2NF COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) 2NF (Second Normal Form) Rules • Rule 1- Be in 1NF • Rule 2- Single Column Primary Key that does not functionally dependant on any subset of candidate key relation It is clear that we can’t move forward to make our simple database in 2nd Normalization form unless we partition the table above. We have divided our 1NF table into two tables viz. Table 1 and Table2. Table 1 contains member information. Table 2 contains information on movies rented. We have introduced a new column called Membership_id which is the primary key for table 1. Records can be uniquely identified in Table 1 using membership id Database – Foreign Key In Table 2, Membership_ID is the Foreign Key Foreign Key in DBMS COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 362 Foreign Key references the primary key of another Table! It helps connect your Tables • A foreign key can have a different name from its primary key • It ensures rows in one table have corresponding rows in another • Unlike the Primary key, they do not have to be unique. Most often they aren’t • Foreign keys can be null even though primary keys can not Why do you need a foreign key? Suppose, a novice inserts a record in Table B such as COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 363 Page | 364 You will only be able to insert values into your foreign key that exist in the unique key in the parent table. This helps in referential integrity. The above problem can be overcome by declaring membership id from Table2 as foreign key of membership id from Table1 Now, if somebody tries to insert a value in the membership id field that does not exist in the parent table, an error will be shown! What are transitive functional dependencies? A transitive functional dependency is when changing a non-key column, might cause any of the other non-key columns to change Consider the table 1. Changing the non-key column Full Name may change Salutation. Let’s move into 3NF 3NF (Third Normal Form) Rules • Rule 1- Be in 2NF • Rule 2- Has no transitive functional dependencies To move our 2NF table into 3NF, we again need to again divide our table. 3NF Example COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Below is a 3NF example in SQL database: Page | 365 We have again divided our tables and created a new table which stores Salutations. There are no transitive functional dependencies, and hence our table is in 3NF In Table 3 Salutation ID is primary key, and in Table 1 Salutation ID is foreign to primary key in Table 3 Now our little example is at a level that cannot further be decomposed to attain higher normal form types of normalization in DBMS. In fact, it is already in higher normalization forms. Separate efforts for moving into next levels of normalizing data are normally needed in complex databases. However, we will be discussing next levels of normalisation in DBMS in brief in the following. BCNF (Boyce-Codd Normal Form) Even when a database is in 3rd Normal Form, still there would be anomalies resulted if it has more than one Candidate Key. Sometimes is BCNF is also referred as 3.5 Normal Form. 4NF (Fourth Normal Form) Rules If no database table instance contains two or more, independent and multivalued data describing the relevant entity, then it is in 4th Normal Form. 5NF (Fifth Normal Form) Rules A table is in 5th Normal Form only if it is in 4NF and it cannot be decomposed into any number of smaller tables without loss of data. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) 6NF (Sixth Normal Form) Proposed 6th Normal Form is not standardized, yet however, it is being discussed by database experts for some time. Hopefully, we would have a clear & standardized definition for 6th Normal Form in the near future BENEFITS OF DATA NORMALIZATION As mentioned above, the most important part of data normalization is better analysis leading to growth; however, there are a few more incredible benefits of this process: More space With databases crammed with information, organization and elimination of duplicates frees up much-needed gigabyte and terabyte space. When a system is loaded with unnecessary things, the processing performance decreases. After cleaning digital memory, your systems will run faster and load quicker, meaning data analysis is done at a more efficient rate. Faster question answering Speaking of faster processes, after normalization becomes a simple task, you can organize your data without any need to further modify. This helps various teams within a company save valuable time instead of trying to translate crazy data that hasn’t been stored properly. Better segmentation One of the best ways to grow a business is to ensure lead segmentation. With data normalization, groups can be rapidly split into categories based on titles, industries—you name it. Creating lists based on what is valuable to a specific lead is a process that no longer causes a headache. Data normalization is not an option As data becomes more valuable to all types of business, the way it is organized in mass qualities cannot be overlooked. From ensuring the delivery of emails to preventing misdials and improving analysis of groups without the worry of duplicates, it is easy to see that when data normalization is performed correctly it results in better overall business function. Just imagine if you leave your data in disarray and miss important growth opportunities due to a website not loading or notes not getting to a VP. None of that sounds like success or growth. Entity-relationship diagrams ENTITY-RELATIONSHIP DIAGRAMS An Entity–relationship model (ER model) describes the structure of a database with the help of a diagram, which is known as Entity Relationship Diagram (ER Diagram). An ER model is a design or blueprint of a database that can later be implemented as a database. The main components of E-R model are: entity set and relationship set. What is an Entity Relationship Diagram (ER Diagram)? COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 366 An ER diagram shows the relationship among entity sets. An entity set is a group of similar entities and these entities can have attributes. In terms of DBMS, an entity is a table or attribute of a table in database, so by showing relationship among tables and their attributes, ER diagram shows the complete logical structure of a database. Lets have a look at a simple ER diagram to understand this concept. A simple ER Diagram: In the following diagram we have two entities Student and College and their relationship. The relationship between Student and College is many to one as a college can have many students however a student cannot study in multiple colleges at the same time. Student entity has attributes such as Stu_Id, Stu_Name & Stu_Addr and College entity has attributes such as Col_ID & Col_Name. Here are the geometric shapes and their meaning in an E-R Diagram. We will discuss these terms in detail in the next section(Components of a ER Diagram) of this guide so don’t worry too much about these terms now, just go through them once. Rectangle: Represents Entity sets. Ellipses: Attributes Diamonds: Relationship Set Lines: They link attributes to Entity Sets and Entity sets to Relationship Set Double Ellipses: Multivalued Attributes Dashed Ellipses: Derived Attributes Double Rectangles: Weak Entity Sets Double Lines: Total participation of an entity in a relationship set Components of a ER Diagram COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 367 Page | 368 As shown in the above diagram, an ER diagram has three main components: 1. Entity 2. Attribute 3. Relationship 1. Entity An entity is an object or component of data. An entity is represented as rectangle in an ER diagram. For example: In the following ER diagram we have two entities Student and College and these two entities have many to one relationship as many students study in a single college. We will read more about relationships later, for now focus on entities. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 369 Weak Entity: An entity that cannot be uniquely identified by its own attributes and relies on the relationship with other entity is called weak entity. The weak entity is represented by a double rectangle. For example – a bank account cannot be uniquely identified without knowing the bank to which the account belongs, so bank account is a weak entity. 2. Attribute An attribute describes the property of an entity. An attribute is represented as Oval in an ER diagram. There are four types of attributes: 1. Key attribute 2. Composite attribute 3. Multivalued attribute 4. Derived attribute 1. Key attribute: A key attribute can uniquely identify an entity from an entity set. For example, student roll number can uniquely identify a student from a set of students. Key attribute is represented by oval same as other attributes however the text of key attribute is underlined. 2. Composite attribute: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 370 An attribute that is a combination of other attributes is known as composite attribute. For example, In student entity, the student address is a composite attribute as an address is composed of other attributes such as pin code, state, country. 3. Multivalued attribute: An attribute that can hold multiple values is known as multivalued attribute. It is represented with double ovals in an ER Diagram. For example – A person can have more than one phone numbers so the phone number attribute is multivalued. 4. Derived attribute: A derived attribute is one whose value is dynamic and derived from another attribute. It is represented by dashed oval in an ER Diagram. For example – Person age is a derived attribute as it changes over time and can be derived from another attribute (Date of birth). E-R diagram with multivalued and derived attributes: 3. Relationship COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) A relationship is represented by diamond shape in ER diagram, it shows the relationship among entities. There are four types of relationships: 1. One to One 2. One to Many 3. Many to One 4. Many to Many 1. One to One Relationship When a single instance of an entity is associated with a single instance of another entity then it is called one to one relationship. For example, a person has only one passport and a passport is given to one person. 2. One to Many Relationship When a single instance of an entity is associated with more than one instances of another entity then it is called one to many relationship. For example – a customer can place many orders but a order cannot be placed by many customers. 3. Many to One Relationship COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 371 When more than one instances of an entity is associated with a single instance of another entity then it is called many to one relationship. For example – many students can study in a single college but a student cannot study in many colleges at the same time. 4. Many to Many Relationship Page | 372 When more than one instances of an entity is associated with more than one instances of another entity then it is called many to many relationship. For example, a can be assigned to many projects and a project can be assigned to many students. Total Participation of an Entity set A Total participation of an entity set represents that each entity in entity set must have at least one relationship in a relationship set. For example: In the below diagram each college must have at-least one associated Student. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) UNIT 4 DATABASE IMPLEMENTATION Introduction to a DBMS (e.g. MY SQL) INTRODUCTION TO A DBMS (E.G. MY SQL) A database management system (DBMS) refers to the technology for creating and managing databases. DBMS is a software tool to organize (create, retrieve, update, and manage) data in a database. The main aim of a DBMS is to supply a way to store up and retrieve database information that is both convenient and efficient. By data, we mean known facts that can be recorded and that have embedded meaning. Usually, people use software such as DBASE IV or V, Microsoft ACCESS, or EXCEL to store data in the form of a database. A datum is a unit of data. Meaningful data combined to form information. Hence, information is interpreted data - data provided with semantics. MS. ACCESS is one of the most common examples of database management software. More on Data, Information, and Knowledge Knowledge refers to the useful use of information. As you know, that information can be transported, stored, and shared without any problems and difficulties, but the same cannot be said about knowledge. Knowledge necessarily involves personal experience and practice. Database systems are meant to handle an extensive collection of information. Management of data involves both defining structures for storage of information and providing mechanisms that can do the manipulation of those stored information. Moreover, the database system must ensure the safety of the information stored, despite system crashes or attempts at unauthorized access. WHY USE DBMS? • To develop software applications in less time. • Data independence and efficient use of data. • For uniform data administration. • For data integrity and security. • For concurrent access to data, and data recovery from crashes. • To use user-friendly declarative query language. WHERE IS A DATABASE MANAGEMENT SYSTEM (DBMS) BEING USED? • Telecom: There is a database to keeps track of the information regarding calls made, network usage, customer details etc. Without the database systems it is hard to maintain that huge amount of data that keeps updating every millisecond. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 373 • Industry: Where it is a manufacturing unit, warehouse or distribution centre, each one needs a database to keep the records of ins and outs. For example, distribution centre should keep a track of the product units that supplied into the centre as well as the products that got delivered out from the distribution centre on each day; this is where DBMS comes into picture. • Banking System: For storing customer info, tracking day to day credit and debit transactions, generating bank statements etc. All this work has been done with the help of Database management systems. • Sales: To store customer information, production information and invoice details. • Airlines: To travel though airlines, we make early reservations, this reservation information along with flight schedule is stored in database. • Education sector: Database systems are frequently used in schools and colleges to store and retrieve the data regarding student details, staff details, course details, exam details, payroll data, attendance details, fees details etc. There is a hell lot amount of inter-related data that needs to be stored and retrieved in an efficient manner. Online shopping: You must be aware of the online shopping websites such as Amazon, Flipkart etc. These sites store the product information, your addresses and preferences, credit details and provide you the relevant list of products based on your query. All this involves a Database management system. ADVANTAGES OF DBMS • A DBMS manages data and has many benefits. These are: • Data independence: Application programs should be as free or independent as possible from details of data representation and storage. DBMS can supply an abstract view of the data for insulating application code from such facts. • Efficient data access: DBMS utilizes a mixture of sophisticated concepts and techniques for storing and retrieving data competently. This feature becomes important in cases where the data is stored on external storage devices. • Data integrity and security: If data is accessed through the DBMS, the DBMS can enforce integrity constraints on the data. • Data administration: When several users share the data, integrating the administration of data can offer significant improvements. Experienced professionals understand the nature of the data being managed and can be responsible for organizing the data representation to reduce redundancy and make the data to retrieve efficiently. DISADVANTAGES OF DBMS: • DBMS implementation cost is high compared to the file system • Complexity: Database systems are complex to understand COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 374 • Performance: Database systems are generic, making them suitable for various applications. However, this feature affects their performance for some applications. COMPONENTS OF DBMS • Users: Users may be of any kind such as DB administrator, System developer, or database users. • Database application: Database application may be Departmental, Personal, organization's and / or Internal. • DBMS: Software that allows users to create and manipulate database access, • Database: Collection of logical data as a single unit. CHARACTERISTICS Traditionally, data was organized in file formats. DBMS was a new concept then, and all the research was done to make it overcome the deficiencies in traditional style of data management. A modern DBMS has the following characteristics − • Real-world entity − A modern DBMS is more realistic and uses real-world entities to design its architecture. It uses the behavior and attributes too. For example, a school database may use students as an entity and their age as an attribute. • Relation-based tables − DBMS allows entities and relations among them to form tables. A user can understand the architecture of a database just by looking at the table names. • Isolation of data and application − A database system is entirely different than its data. A database is an active entity, whereas data is said to be passive, on which the database works and organizes. DBMS also stores metadata, which is data about data, to ease its own process. • Less redundancy − DBMS follows the rules of normalization, which splits a relation when any of its attributes is having redundancy in values. Normalization is a mathematically rich and scientific process that reduces data redundancy. • Consistency − Consistency is a state where every relation in a database remains consistent. There exist methods and techniques, which can detect attempt of leaving database in inconsistent state. A DBMS can provide greater consistency as compared to earlier forms of data storing applications like file-processing systems. • Query Language − DBMS is equipped with query language, which makes it more efficient to retrieve and manipulate data. A user can apply as many and as different filtering options as required to retrieve a set of data. Traditionally it was not possible where file-processing system was used. • ACID Properties − DBMS follows the concepts of Atomicity, Consistency, Isolation, and Durability (normally shortened as ACID). These concepts are applied on COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 375 transactions, which manipulate data in a database. ACID properties help the database stay healthy in multi-transactional environments and in case of failure. • Multiuser and Concurrent Access − DBMS supports multi-user environment and allows them to access and manipulate data in parallel. Though there are restrictions on transactions when users attempt to handle the same data item, but users are always unaware of them. • Multiple views − DBMS offers multiple views for different users. A user who is in the Sales department will have a different view of database than a person working in the Production department. This feature enables the users to have a concentrate view of the database according to their requirements. • Security − Features like multiple views offer security to some extent where users are unable to access data of other users and departments. DBMS offers methods to impose constraints while entering data into the database and retrieving the same at a later stage. DBMS offers many different levels of security features, which enables multiple users to have different views with different features. For example, a user in the Sales department cannot see the data that belongs to the Purchase department. Additionally, it can also be managed how much data of the Sales department should be displayed to the user. Since a DBMS is not saved on the disk as traditional file systems, it is very hard for miscreants to break the code. Implementing databases ENTITY-RELATIONSHIP DIAGRAMS The implementation phase is where you install the DBMS on the required hardware, optimize the database to run best on that hardware and software platform, and create the database and load the data. The initial data could be either new data captured directly or existing data imported from a MariaDB database or another DBMS. You also establish database security in this phase and give the various users that you've identified access applicable to their requirements. Finally, you also initiate backup plans in this phase. THE FOLLOWING ARE STEPS IN THE IMPLEMENTATION PHASE: 1. Install the DBMS. 2. Tune the setup variables according to the hardware, software and usage conditions. 3. Create the database and tables. 4. Load the data. 5. Set up the users and security. 6. Implement the backup regime. Structured query language STRUCTURED QUERY LANGUAGE COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 376 SQL is a programming language used by nearly all relational databases to query, manipulate, and define data, and to provide access control. SQL was first developed at IBM in the 1970s with Oracle as a major contributor, which led to implementation of the SQL ANSI standard, SQL has spurred many extensions from companies such as IBM, Oracle, and Microsoft. Although SQL is still widely used today, new programming languages are beginning to appear. WHAT CAN SQL DO? • SQL can execute queries against a database • SQL can retrieve data from a database • SQL can insert records in a database • SQL can update records in a database • SQL can delete records from a database • SQL can create new databases • SQL can create new tables in a database • SQL can create stored procedures in a database • SQL can create views in a database • SQL can set permissions on tables, procedures, and views USING SQL IN YOUR WEB SITE To build a web site that shows data from a database, you will need: • An RDBMS database program (i.e. MS Access, SQL Server, MySQL) • To use a server-side scripting language, like PHP or ASP • To use SQL to get the data you want • To use HTML / CSS to style the page A query is a way of requesting information from the database. A database query can be either a select query or an action query. A select query is a query for retrieving data, while an action query requests additional actions to be performed on the data, like deletion, insertion, and updating. For example, a manager can perform a query to select the employees who were hired 5 months ago. The results could be the basis for creating performance evaluations. Methods for Creating Queries Selecting Parameters from a Menu COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 377 • In this method, the database system displays a list of parameters for you to choose from. This is the simplest way to create a query because there are menus that guide you, but it is also the least flexible. Query by Example (QBE) • In this method, the system displays a blank record and lets you identify the fields and values that define the query. • This is a method of query creation that authorises the user to look for documents based on an example in the form of a selected text string, or in the form of a document name, or even a list of documents. Because the QBE system develops the actual query, QBE is easier to grasp than formal query languages, while still enabling powerful searches. • In terms of database management systems, QBE can be considered a ‘fill-in-the-blanks’ method of query creation. An example of QBE is the Microsoft Access Query Design Grid. The user inputs criteria into the form to create search conditions for as many fields as desired, in order to perform a search. A query is then automatically created to search the database for corresponding data. QUERY LANGUAGE Many database systems expect you to make requests for information through a stylised query written in a specific query language. This is the most complicated method because it compels you to learn a specific language, but it is also the most flexible. Query languages are used to create queries in a database. EXAMPLES OF QUERY LANGUAGES Microsoft Structured Query Language (SQL) is the ideal query language. Other expansions of the language under the SQL query umbrella include: • MySQL • Oracle SQL • NuoDB Query languages for other types of databases, such as NoSQL databases and graph databases, include the following: • Cassandra Query Language (CQL) • Neo4j’s Cypher • Data Mining Extensions (DMX) • XQuery POWER OF QUERIES COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 378 A database has the possibility to uncover intricate movements and actions, but this power is only utilised through the use of query. A complex database contains multiple tables storing countless amounts of data. A query lets you filter it into a single table, so you can analyse it much more easily. Queries also can execute calculations on your data, summarise your data for you, and even Page | 379 automate data management tasks. You can also evaluate updates to your data prior to committing them to the database, for still more versatility of usage. Queries can perform a number of various tasks. Mainly, queries are used to search through data by filtering specific criteria. Other queries contain append, crosstab, delete, make table, parameter, totals, and update tools, each of which performs a specific function. For example, a parameter query executes the distinctions of a specific query, which triggers a user to enter a field value, and then it makes use of that value to make the criteria. In comparison, totals queries let users organise and summarise data. In a relational database, which is composed of records or rows of data, the SQL SELECT statement query lets the user select data and deliver it to an application from the database. The resulting query is saved in a result-table, which is referred to as the result-set. The SELECT statement can be divided into other specific statements, like FROM, ORDER BY and WHERE. The SQL SELECT query can also group and combine data, which could be useful for creating analyses or summaries. DATABASE QUERY METHODS Query Methods This chapter describes the different query methods you can use in your ConText application. You can use these methods with text queries and theme queries. The following topics are covered: Selecting a Query Method Each of the query methods (two-step, one-step, and in-memory) provide advantages and disadvantages that you must consider when developing an application. The following table briefly describes each method and illustrates the various advantages and disadvantages to using each: Query Method One-step Use Used in SQL*Plus. Best suited for interactive queries. Advantage • • • No pre-allocation of result tables Uses standard SQL statements Uses table and column names COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Disadvantage • • Generally slower than two-step or in-memory queries No access to result tables • • Two-step Two-step queries are best suited for PL/SQL-based applications that require all the results to a query. • • • • Inmemory In-memory queries are best suited for PL/SQLbased applications that might generate large hitlists, but where only a small portion of the hits are required at a time, such as World Wide Web applications. • • • • Query results returned in a single step Can retrieve all hits at once Result tables can be manipulated Generally faster than one-step queries, especially for mixed queries Can retrieve all hits at once Structured data can be queried as part of the CONTAINS (first step) • No result tables Faster response time than twostep, since you need not retrieve all hits in the hitlist. Large hitlists generally faster than one-step and two-step queries Can specify the number of hits returned • • • • • • • • • USING TWO-STEP QUERIES To perform a two-step query, do the following: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Requires preallocation of result tables Uses policy names Requires two steps to complete Requires join to base text table to return document details Uses policy names Cannot retrieve all hits at once With small hitlists, performance improvement over two-step is negligible Requires three steps, including a loop, to complete Queries for structured data must be performed separately and joined with inmemory results Max and first/next operators are not supported Page | 380 1. Execute CTX_QUERY.CONTAINS. The procedure selects all documents that match the specified search criteria (query expression) and generates a score for each document. The document textkeys and scores are stored in the specified result table. Note: You must create the result table before you execute the CONTAINS procedure. 2. Use a SELECT statement on the result table (and the base text table, if desired) to return the specified columns as a hitlist for the rows (documents) that satisfy the query expression. Two-Step Query Example The following example shows a simple two-step query. The query uses a policy named ARTICLES_POL to search the text column in a table named TEXTTAB for any articles that contain the word petroleum. The CONTAINS procedure populates the CTX_TEMP results table with the document primary keys that satisfy the query. The select statement then joins the results in CTX_TEMP with TEXTAB to create a list of document titles ordered by score. Note that before the two-step query example is executed, the result table, CTX_TEMP, is created: create table CTX_TEMP( textkey varchar2(64), score number, conid number); execute ctx_query.contains('ARTICLE_POLICY','petroleum','CTX_TEMP') SELECT SCORE, title FROM CTX_TEMP, TEXTTAB WHERE texttab.PK=ctx_temp.textkey COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 381 ORDER BY SCORE DESC; In this example, the articles with the highest scores appear first in the hitlist because the results are sorted by score in descending order. Scoring In a two-step query, the score results generated by the CONTAINS procedure are physically stored in a result table that has been allocated (either by the application developer or dynamically within the application). If you want to include scores in the hitlist returned by a two-step query, select the from the result table in the second step of the query. . Note: The way in which ConText calculates a relevance score for text queries is different than the way it calculates scores for theme queries. To learn more about how ConText calculates relevance score for text queries, see "Scoring" in Chapter 1. To learn more about how ConText calculates relevance scores for theme queries, see "Understanding Theme Queries" in Chapter 4. Hitlist Result Tables In two-step queries, ConText uses result tables called hitlist tables to store intermediate results. Intermediate results can be merged into the standard SQL query through a join operation or a sub-query operation. The result tables must be created before the query is performed. A hitlist table can be created manually or allocated through the CTX_QUERY.GETTAB procedure. Hitlist tables can be named anything; however, they must have the following structure: Column Name Column Datatype Purpose TEXTKEY VARCHAR2(64) Stores textkeys of the rows satisfying the query COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 382 SCORE NUMBER Stores the score for each row (document) CONID NUMBER Stores the CONTAINS ID when multiple CONTAINS procedures utilize the same result table See Also: For more information about the structure of the hitlist result tables, see "Hitlist Table Structure" in Appendix A. Sharing a Hitlist Result Table For applications that support multiple concurrent users, ConText allows for sharing a single result table among all the users rather than allocating a separate table for each user. You control sharing of result tables with the sharelevel and the query_id parameters of the CTX_QUERY.CONTAINS procedure. If the result table is shared, the CONTAINS procedure must specify that sharelevel is equal to one and include a unique query_id so that each result can be distinguished from others in the result table. When sharelevel is equal to 0: • the hitlist result table is intended for exclusive use • ConText truncates the hitlist result table at the start of each query • after the query is completed, CONID values are NULL When sharelevel is equal to 1 then: • the hitlist result table is intended for shared use • specify a unique number for query_id in the CONTAINS procedure to identify which entries belong to you in the hitlist result table. This number will be assigned to the CONID for each row in the result table generated by the query. • before the query is run, you must delete existing rows in the result table with the same query_id as that specified in the CONTAINS procedure • after the query is complete, the CONID column for all rows returned by the query contains the query_id specified in the CONTAINS procedure • select your rows by specifying the appropriate CONID in the WHERE clause of the SELECT statement COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 383 Attention: ConText does not verify that these rules are observed. You must control multiple concurrent usage by passing a different query_id to the requestor if the result table is shared. Composite Text key Result Tables When you execute a two-step query on a table with a composite textkey, the number of textkey columns in the result table must match the composite keys count in the document table. For example, if you want to execute a query on a document table that has a two-column textkey, create a result table with the following schema: TEXTKEY, TEXTKEY2, SCORE, CONID. The following SQL*Plus examples show two different ways in which to create a result table with a two-column composite textkey: /* create composite textkey result table manually */ create table ctx_temp( textkey varchar2(64), textkey2 varchar2(64), score number, conid number); /* allocate composite textkey result table with CTX_QUERY.GETTAB() */ exec ctx_query.gettab(CTX_QUERY.HITTAB, :hit_tab, 2) See Also: For more information on the structure of composite textkey result tables, see "Composite Textkey Hitlist Tables" in Appendix A. SELECT from a Pre-defined View There is an alternative to the second step of a two-step query. Rather than joining the result table and text table in a SELECT statement, you can create a view to perform the join. Then use a COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 384 SELECT statement to select the appropriate rows from that view. Use this approach when the development tool does not allow tables to be joined in a SELECT statement (e.g. Oracle Forms). For example: CREATE VIEW SURVEY AS SELECT * FROM TEXTTAB, CTX_TEMP WHERE PK = TEXTKEY; SELECT SCORE, AUTHOR FROM SURVEY ORDER BY SCORE DESC; In this example: • The CREATE VIEW statement joins the table of articles (TEXTTAB) and the result table (CTX_TEMP). The PK column holds the primary key of the documents. • The SELECT statement retrieves the scores from the view. Composite Textkey Queries To execute a two-step query on a table with a composite textkey, you first specify the multiple textkey columns when you create the policy for the text column. See Also: For more information about creating policies for composite textkey tables, see Oracle ConText Option Administrator's Guide. In addition, before the two-step query, create a result table in which the number of TEXTKEY columns match the number of columns in the composite textkey in the document table. You can create the result table manually or using the CTX_QUERY.GETTAB procedure. See Also: For more information on the structure of composite textkey result tables, see "Composite Textkey Hitlist Tables" in Appendix A. For example, to create a result table manually with a composite textkey consisting of two columns, issue the following SQL statement: create table CTX_TEMP2( COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 385 textkey varchar2(64), textkey2 varchar2(64), score number, conid number); In the two-step query, use the AND operator in the WHERE condition when you join the result and text tables. For example: exec ctx_query.contains('ARTICLE2_POLICY',\ 'petroleum',\ 'CTX_TEMP2') SELECT SCORE, title FROM CTX_TEMP2, TEXTTAB2 WHERE texttab2.PK=ctx_temp2.textkey AND texttab2.PK2=ctx_temp2.textkey2 ORDER BY SCORE DESC; Structured Queries A structured query is a query based on a text column and a structured data column. The structured data column is usually in the same table as the text column. For example, you might use a structured query to retrieve documents on a certain subject that were written after a certain date, where the document content is in a text column and date information is in a structured data column. The CTX_QUERY.CONTAINS procedure provides an additional parameter, struct_query, for specifying the WHERE condition in a structured query. For example, to select all news articles that contain the word Oracle that were written on or after October 1st, 1996, you might use: exec ctx_query.contains('news_text','Oracle','res_tab',\ struct_query => 'issue_date >= (''1-OCT-1996'')') Note: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 386 Because the struct_query parameter expects a WHERE condition, you can specify a subquery. This is useful when the structured data column is in another table. Page | 387 Executing a structured query with the struct_query parameter improves performance over processing a query on a text column and then refining the hitlist by applying a where condition against a structured column. This is especially so when the selectivity of the WHERE condition is high, because when you use the structured query parameter, the ConText server executes the entire query without first writing out a potentially large hitlist to be refined later by the Oracle server. Note: If the user who includes a structured query in a two-step query is not the owner of the table containing the structured and text columns, the user must have SELECT privilege with GRANT OPTION on the table. In addition, if the object being queried is a view, the user must have SELECT privilege with GRANT OPTION on the base table for the view. SELECT privilege with GRANT OPTION can be granted to a user using the GRANT command in SQL. For more information, see Oracle7 Server SQL Reference. Querying Columns in Remote Databases If a database link has been created for a remote database, two-step queries support querying text columns in the remote database. Note: Database links are created using the CREATE DATABASE LINK command in SQL. For more information about creating database links, see Oracle7 Server SQL Reference. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) To perform a two-step query for a text column in a remote database, specify the database link for the remote database in the CONTAINS procedure as part of the policy for the column in the remote database. In addition, the result table specified in CONTAINS must exist in the remote database, and you, the user performing the query, must have the appropriate privileges on the result table. For example: exec ctx_query.contains('MY_POL@DB1', 'petroleum','CTX_TEMP') In this example, MY_POL exists in a remote database identified by the database link DB1. The CTX_TEMP result table exists in the same remote database. See Also: For more information about remote queries and distributed databases, see Oracle7 Server Concepts. Two-Step Queries in Parallel The CONTAINS procedure provides an argument for processing two-step queries in parallel. Processing queries in parallel helps balance the load between ConText servers and might improve query performance. When the CONTAINS procedure is called in a two-step query, the PARALLEL argument can be used to specify the number of ConText servers, up to the total number of ConText servers running with the Query personality, that are used to process two-step queries and write the results to the result table. For example: execute ctx_query.contains('ARTICLE_POLICY',\ 'petroleum', 'CTX_TEMP', parallel=>2) In this example, the text column in the ARTICLE_POLICY policy is queried for documents that contain the term petroleum. The query is processed in parallel by any two available ConText servers with the Query personality and the results are written to CTX_TEMP. USING ONE-STEP QUERIES The one-step query uses the CONTAINS and SCORE functions in a SQL statement to execute a user's request for documents. Rows and columns containing the text and structured data for COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 388 relevant documents are returned to the application program as a record set like any other query in SQL. . Note: Before one-step queries can be executed, the database in which the text resides must be text enabled by setting the ConText initialization parameter TEXT_ENABLE = TRUE. This can be done by either setting it in the initsid.ora system initialization file, or by using the ALTER SESSION command. For more information about initialization parameters and the initsid.ora file, see Oracle7 Server Administrator's Guide. For more information about using the ALTER SESSION command, see Oracle7 Server SQL Reference. One-Step Query Processing After a user has submitted a one-step query, ConText performs the following tasks to return the results to the user: 1. The query is placed on the text queue (query pipe). The Oracle server intercepts the query and passes the text portion (CONTAINS) to ConText. 2. A ConText server with the Query personality picks up the text portion of the query, processes the CONTAINS function(s) and stores the results in an internal table created automatically for the user who submitted the query. This table (and the corresponding intermediate results) are not available to the application. 3. The ConText server rewrites the query as a standard SQL statement and passes it back to Oracle. 4. The rewritten query is executed by an Oracle server and the results are returned to the user. 5. The internal result table is truncated. One-Step Query Example The following SELECT statement shows a simple one-step query. This query searches a text table called TEXTTAB for any articles that contain the word petroleum. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 389 SELECT * FROM texttab WHERE CONTAINS (text, 'petroleum') > 0; Page | 390 Because ConText functions execute within normal SQL statements, all of the capabilities for selecting and querying normal structured data fields, as well as text, are available. For instance, in the example, if the text table had a column listing the date the article was published, the user could select articles based on that date as well as the content of the text column. . Note: The asterisk wildcard character ( *) in specifies that the record set returned by the query includes all the columns of the text table for the selected documents, as well as the scores generated for each document. If a query has more than one CONTAINS function, the asterisk wildcard does not return scores for the multiple CONTAINS and the SCORE function must be called explicitly. See "Scoring" in this chapter for an example. Multiple CONTAINS One-step queries support calling more than one CONTAINS functions in the WHERE clause of a SELEC statement. Multiple CONTAINS can be used in a one-step query to perform queries on multiple text columns located either in the same table or in separate tables. If multiple ConText servers with the Query personality are running and a one-step query with multiple CONTAINS is executed, the query is processed in parallel. Each CONTAINS function is evaluated by one of the available ConText servers and the results from the servers are combined before they are returned to the user. Suggestion: If your application makes use of multiple CONTAINS in one-step queries, ensure that multiple ConText servers with the Query personality are running to optimize query performance. The number of ConText servers should be at least equal to the number of CONTAINS you support in one-step queries for the application. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Scoring In a one-step query, the document scores are generated by the CONTAINS function and returned Page | 391 by the SCORE function. Each CONTAINS function in a query produces a separate score. When there are multiple CONTAINS functions, each CONTAINS function must have a label (a number) so the SCORE value can be identified in other clauses of the SELECT statement. The SCORE function may be used in a SELECT list, an ORDER BY clause or a GROUP BY clause. For example: SELECT SCORE (10), SCORE(20), title FROM DOCUMENTS WHERE CONTAINS (TEXT, 'holmes', 10) OR CONTAINS (TEXT, 'moriarty', 20) OR CONTAINS (TEXT, 'baker street', 30) ORDER BY SCORE(10) GROUP BY SCORE(30) Note: The way in which ConText calculates a relevance score for text queries is different than the way it calculates scores for theme queries. To learn more about how ConText calculates relevance score for text queries, see "Scoring" in Chapter 1. To learn more about how ConText calculates relevance scores for theme queries, see "Understanding Theme Queries" in Chapter 4. Restrictions The CONTAINS function can only appear in the WHERE clause of a SELECT statement. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) You cannot issue the CONTAINS function in the WHERE clause of an UPDATE, INSERT or DELETE statement. Composite Textkey Queries You can perform one-step queries on text tables with composite textkeys. The syntax for the query is the same as the syntax for a query on a table with a single-column textkey. Querying Columns in Remote Databases If a database link has been created for a remote database, one-step queries support querying text columns in the remote database. To perform a one-step query for a text column in a remote database, the database link for the remote database is specified as part of the table name in the SELECT clause. For example: SELECT * FROM texttab@db1 WHERE CONTAINS (text, 'petroleum') > 0; In this example, texttab exists in a remote database identified by the database link DB1 Note: One-step queries do not support querying LONG and LONG RAW columns in remote database tables. USING IN-MEMORY QUERIES In-memory queries use a buffer and a cursor to return query results. Returning query results to a buffer in memory improves performance over writing and reading query results to and from database result tables, which is typical of one- and two-step queries. To perform an in-memory query, do the following: 1. Call the CTX_QUERY.OPEN_CON function. OPEN_CON performs the following operations: o opens a cursor to the query buffer o queries a text column using the specified policy and query expression o stores in the query buffer the document textkeys and scores for all the documents that meet the search criteria. Hits are stored in order that they are returned or ranked by score, depending on the argument specified for OPEN_CON COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 392 In addition, you can specify that OPEN_CON return additional columns (up to five) for the selected documents from the text table. 2. Call the CTX_QUERY.FETCH_HIT function for each textkey in the buffer to fetch the desired query results, one hit at a time, until the desired number of hits has been returned or no hits remain in the buffer. 3. Call the CTX_QUERY.CLOSE_CON procedure to release the cursor opened by OPEN_CON. In-Memory Query Example The following example shows a simple in-memory query. This query uses a policy named ARTICLES_POL to search the text column in a table named TEXTTAB for any articles that contain the word petroleum. declare score char(5); pk char(5); curid number; title char(256); begin dbms_output.enable(100000); curid := ctx_query.open_con( policy_name => 'ARTICLES_POL', text_query => 'petroleum', score_sorted => true, other_cols => 'title'); while (ctx_query.fetch_hit(curid, pk, score, title)>0) loop dbms_output.put_line(score||pk||substr(title,1,50)); end loop; ctx_query.close_con(curid); end; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 393 In this example, the TITLE column from the table is also returned by OPEN_CON, so a variable must be declared for TITLE. DBMS_OUTPUT.ENABLE sets the buffer size to the maximum of 100000 bytes (1 Mb) to ensure that the buffer is large enough to hold the results of the query. The SCORE_SORTED argument in OPEN_CON is set to true which causes OPEN_CON to store the hits in the query buffer in descending order by score. FETCH_HIT is called in a loop to fetch SCORE, PK, and TITLE for each hit until a value less than zero is returned, indicating that the buffer is empty. DBMS_OUTPUT.PUT_LINE prints the results to the standard output. See Also: For more information about the DBMS_OUTPUT PL/SQL package, see Oracle7 Server Application Developer's Guide. In-Memory Queries and Composite Textkeys You can perform in-memory queries on text tables that have multiple column textkeys. When you use CTX_QUERY.FETCH_HIT to retrieve each hit from the buffer, the PK argument is returned as an encoded string. To access an individual textkey, you must use CTX_QUERY.PKDECODE. In-Memory Query Limitations In-memory queries have the following limitation: Max and First/Next Operators You cannot use the max and first/next operators with in-memory queries. Querying Columns in Remote Databases If a database link has been created for a remote database, in-memory queries support querying text columns in the remote database. Note: Database links are created using the CREATE DATABASE LINK command in SQL. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 394 For more information about creating database links, see Oracle8 Server SQL Reference. Page | 395 To perform an in-memory query for a text column in a remote database, the database link for the remote database is specified in the CTX_QUERY.OPEN_CON procedure as part of the policy for the column in the remote database. In addition, the result table specified in CTX_QUERY.CONTAINS must exist in the remote database and the user performing the query must have the appropriate privileges on the result table. Counting Query Hits In addition to two-step, one-step, and in-memory queries, you can count the number of hits in a two-step or in-memory query. The documents can be stored in a local or remote database. Counting query hits helps to audit queries to ensure large and unmanageable hitlists are not returned. You can count the number of hits before or after you issue the query using one of the following functions: • CTX_QUERY.COUNT_HITS • CTX_QUERY.COUNT_LAST Using COUNT_HITS Before the Query Before you issue a two-step or in-memory query, you can use the CTX_QUERY.COUNT_HITS function to return the number of hits for the query without generating scores for the hits or returning the textkeys for the documents. COUNT_HITS can be called in two modes, estimate and exact. The results in estimate mode may be inaccurate; however, the results are generally returned faster than in exact mode . See Also: CTX_QUERY.COUNT_HITS in Chapter 10. Using COUNT_LAST After the Query You can use the CTX.QUERY.COUNT_LAST function to obtain the number of hits in a twostep query and in-memory query after issuing CONTAINS or OPEN_CON. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) COUNT_LAST returns the number of hits obtained from the last call to CTX_QUERY.CONTAINS or CTX_QUERY.OPEN_CON. For two-step queries, the time it takes to issue the query with CONTAINS and then to call COUNT_LAST is not as fast as calling COUNT_HITS before the query. However, in the case where you need to process all hits in a two-step query, issuing the query with CONTAINS and then calling COUNT_LAST is more efficient than calling COUNT_HITS and then calling CONTAINS. With in-memory queries, issuing OPEN_CON and then calling COUNT_LAST is always a more efficient way to obtain an estimate of the query hits over calling COUNT_HITS and then calling OPEN_CON, since COUNT_LAST returns a number faster than COUNT_HITS. Advanced database concepts (triggers, stored procedures) ADVANCED DATABASE CONCEPTS (TRIGGERS, STORED PROCEDURES) This chapter compares MySQL and Oracle triggers and stored procedures. (The information in this chapter applies only to MySQL release 5, not to earlier releases.) For more information about Oracle triggers and stored procedures, see the PL/SQL User's Guide and Reference. This chapter includes the following sections: TRIGGERS Triggers are named database objects that are implicitly fired when a triggering event occurs. The trigger action can be run before or after the triggering event. Triggers are similar to stored procedures but differ in the way that they are invoked. Support for triggers in MySQL is only included beginning with release 5.0.2. A trigger can only be associated with a table and defined to fire when an INSERT, DELETE or UPDATE statement is performed on the table. MySQL does not permit two triggers with the same trigger timing (BEFORE or AFTER) and trigger event or statement (INSERT, DELETE, or UPDATE) to be defined on a table. For example, you cannot define two BEFORE INSERT or two AFTER UPDATE triggers for a table. All triggers defined on MySQL are row triggers, which means that the action defined for the triggers is executed for each row affected by the triggering statement. Error handling during trigger execution for transactional tables ensures that either both the triggering statement and trigger action is completed successfully or neither the trigger statement nor the trigger action is executed, that is all changes made are rollback on failure. For nontransactional tables, all changes made prior to the point of error remains in effect. The following is the syntax to create a trigger in MySQL: CREATE TRIGGER <trigger name> { BEFORE | AFTER } { INSERT | UPDATE | DELETE } ON <table name> COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 396 FOR EACH ROW <triggered action> In Oracle, triggers can be fired when one of the following operations occurs: • DML statements (INSERT, DELETE or UPDATE) that modify data on a table or view • DDL statements • User events such as logon and logoff • System events such as startup, shutdown, and error messages Oracle allows multiple triggers with the same trigger timing and trigger event to be defined on a table; however, these triggers are not guaranteed to execute in any specific order. Triggers can be defined as row triggers or statement triggers. Statement triggers are fired once for each triggering statement regardless of the number of rows in a table affected by the triggering statement. For example if a DELETE statement deletes several rows from a table, a statement trigger is only fired once. The execution model for Oracle triggers is transactional. All actions performed as a result of the triggering statement, including the actions performed by fired triggers, must all succeed; otherwise, they are rolled back. STORED PROCEDURES Stored procedures provide a powerful way to code application logic that can be stored on the server. MySQL and Oracle both use stored procedures and functions. Stored functions are similar to procedures, except that a function returns a value to the environment in which it is called. In MySQL, stored procedures and functions are collectively called routines. The following sections compare stored procedures in MySQL and Oracle: • Individual SQL Statements • Variables in Stored Procedures • Error Handling in Stored Procedures 3.2.1 Individual SQL Statements This section describes considerations related to the following statements or constructs: • REPLACE Statement • DO Statement • Compound DECLARE Statement • Compound SET Statement 3.2.1.1 REPLACE Statement COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 397 The REPLACE statement in MySQL is a dual-purpose statement. It works like the INSERT statement when there is no record in the table that has the same value as the new record for a primary key or a unique index, and otherwise it works like the UPDATE statement. Oracle does not have any built-in SQL statements that supports the purposes of the MySQL REPLACE statement. To convert this statement to Oracle, an emulated function using both the INSERT and UPDATE statements has to be created. An attempt is first made to place the data into the table using the INSERT statement; and if this fails, the data in the table is then updated using the UPDATE statement. 3.2.1.2 DO Statement As its name implies, the DO statement in MySQL does something but does not return anything; specifically, it executes the comma-delimited list of expressions specified as its parameters. The DO statement is converted to a SELECT expr1 [, expr2,…] INTO … FROM DUAL statement in Oracle. 3.2.1.3 Compound DECLARE Statement MySQL uses the DECLARE statement to declare local variables in stored procedures. PL/SQL does not allow multiple declarations; each declaration must be made separately. To convert compound DECLARE statements into functionally equivalent PL/SQL code, each MySQL multiple declaration statement should be converted into logically equivalent separate statements, one for each declaration. For example, consider the following MySQL simple declaration and multiple declaration statements: /* Simple declaration */ DECLARE a INT; /* Compound declaration */ DECLARE a, b INT DEFAULT 5; The PL/SQL functionally equivalent statements are: /* Simple declaration */ a INT; /* Multiple declarations */ a INT := 5; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 398 b INT := 5; In this example, the two original MySQL DECLARE statements are converted into three logically equivalent PL/SQL declaration statements, with one PL/SQL declaration statement for every declaration used within the MySQL DECLARE statements. 3.2.1.4 Compound SET Statement MySQL uses the SET statement to assign values to variables (user variables or system variables). MySQL allows compound statements that assign values to two or more variables within the same statement. PL/SQL allows only simple assignments that assign a single value to a single variable. To convert compound SET statements into functionally equivalent PL/SQL code, split each MySQL multiple assignment statement into logically equivalent simple assignment statements. For example, consider the following MySQL simple assignment and multiple assignment statements: /* Simple statement */ SET a:=1; /* Compound statement*/ SET x:=1, y:=0; The PL/SQL functionally equivalent statements are: /* Simple statement */ a:=1; /* Multiple statements */ x:=1; y:=0; In this example, the two original MySQL SET statements are converted into three logically equivalent PL/SQL assignment statements, with one PL/SQL assignment statement for every declaration used within the MySQL SET statements. 3.2.2 Variables in Stored Procedures COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 399 MySQL supports three types of variables in stored procedures: local variables, user variables, and system variables. Local variables are declared within stored procedures and are only valid within the BEGIN…END block where they are declared. Local variables must be declared within a BEGIN…END block before they can be referenced in other statements in the block, including any nested BEGIN…END blocks. If a local variable declared within a nested BEGIN…END block has the same name as a local variable declared in its enclosing BEGIN…END block, the local variable in the nested block takes precedence wherever the local variable is referenced in the nested BEGIN…END block. Local variables can have any SQL data type. The following example shows the use of local variables in a stored procedure. CREATE PROCEDURE p1() BEGIN /* declare local variables */ DECLARE x INT DEFAULT 0; DECLARE y, z INT; /* using the local variables */ SET x := x + 100; SET y := 2; SET z := x + y; BEGIN /* local variable in nested block */ DECLARE z INT; SET z := 5; /* local variable z takes precedence over the one of the same name declared in the enclosing block. */ SELECT x, y, z; END; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 400 SELECT x, y, z; END; Page | 401 mysql> call p1(); +-----+---+---+ |x |y|z| +-----+---+---+ | 100 | 2 | 5 | +-----+---+---+ 1 row in set (0.00 sec) +-----+---+-----+ |x |y|z | +-----+---+-----+ | 100 | 2 | 102 | +-----+---+-----+ 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec) User variables are specific to a user session and cannot be seen or used by other users. They are valid only for the duration of a user session and are automatically freed when the user session ends. User variables have a session-scope; thus, all references to a user variable of the same name within a session refer to the same variable. In MySQL stored procedures, user variables are referenced with an ampersand (@) prefixed to the user variable name (for example, @x and @y). The following example shows the use of user variables in two stored procedures. CREATE PROCEDURE p2() BEGIN SET @a = 5; SET @b = 5; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) SELECT @a, @b; END; CREATE PROCEDURE p3() BEGIN SET @a = @a + 10; SET @b = @b - 5; SELECT @a, @b; END; mysql> call p2(); +------+------+ | @a | @b | +------+------+ |5 |5 | +------+------+ 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec) mysql> call p3(); +------+------+ | @a | @b | +------+------+ | 15 | 0 | +------+------+ 1 row in set (0.00 sec) COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 402 Query OK, 0 rows affected (0.00 sec) In the second procedure (p3) in the preceding example, the use of the user variables a and b on the right-hand side of the assignment statement assumed that the variables have previously been initialized to some value by the first procedure. If the variables have not been initialized by the first procedure, they would have null values, and the result for the assignment would also be a null value. System variables can also be referenced in MySQL stored procedures. There are two kinds of system variable in MySQL: global system variables and session system variables. Global system variables affect the operation of the overall server. Session system variables affect the individual user session. System variables that are dynamic can also be changed in MySQL stored procedures. In a SET statement, variables name preceded by GLOBAL or @@global. are global variables, and session variables name can optionally be preceded by SESSION, @@session., LOCAL or @@local.. System variables can be referenced in SELECT statement using the @@[global.|session.|local.]var_name syntax. If global., session., or local. is not present, MySQL returns the SESSION variable if it exists or the GLOBAL value otherwise. The following example shows some of these syntax options. CREATE PROCEDURE p4() BEGIN /* setting the value of a (dynamic) global variable */ SET GLOBAL sort_buffer_size := 10000; /* retrieving the value of a global variable */ SELECT @@global.sort_buffer_size; /* setting the value of a (dynamic) session variable */ SET max_join_size := DEFAULT; /* retrieving the value of a session variable, shown using different syntax */ SELECT @@session.max_join_size; SELECT @@local.max_join_size; SELECT @@max_join_size; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 403 END; Oracle PL/SQL also allows variables to be declared and used in stored procedures. As in MySQL, variables in PL/SQL must be declared in the declarative part of a PL/SQL block before they are referenced in any other statements in the block. Local variables in PL/SQL have same scope as local variables in MySQL stored procedures. They are valid within the PL/SQL block where they are declared, including nested PL/SQL blocks. A variable of the same name in a nested PL/SQL block takes precedence over the variable in the enclosing PL/SQL block. As with local variables in MySQL, variables in PL/SQL can have any SQL data type, such as NUMBER or VARCHAR2. In addition, variables in PL/SQL can also have PL/SQL data types, such as BOOLEAN or PLS_INTEGER, or be declared to hold table columns or table rows using the special qualifiers %TYPE and %ROWTYPE. The following example shows some variable declarations in a PL/SQL block. DECLARE /* variables of SQL data-type */ wages NUMBER; hours_worked NUMBER := 40; hourly_salary NUMBER := 22.50; bonus NUMBER := 150; country VARCHAR2(128); counter NUMBER := 0; /* variables of PL/SQL data-types */ done BOOLEAN; valid_id BOOLEAN; /* variables declared to hold table rows */ emp_rec1 employees%ROWTYPE; emp_rec2 employees%ROWTYPE; BEGIN wages := (hours_worked * hourly_salary) + bonus; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 404 country := 'France'; country := UPPER('Canada'); done := (counter > 100); valid_id := TRUE; emp_rec1.first_name := 'Antonio'; emp_rec1.last_name := 'Ortiz'; emp_rec1 := emp_rec2; END; Oracle PL/SQL also allows constants to be declared in stored procedures. Like variables, constants must be declared in the declarative part of a PL/SQL block before they can be referenced in other statements in the PL/SQL block, including nested PL/SQL blocks. A constant is declared with the CONSTANT keyword. A constant must be initialized in its declaration, and no further assignments to the constant are allowed. The following example declares a constant in PL/SQL. credit_limit CONSTANT NUMBER := 5000.00; User variables in MySQL stored procedures can be emulated in Oracle by defining the variables in a package. The package specification emulates the per-session MySQL user variables.Variables defined in a package are available to the users of the package. For an example of a MySQL stored procedure and the converted equivalent in Oracle, consider the following MySQL stored procedure: CREATE PROCEDURE p2() BEGIN SET @a = 5; SET @b = 5; SELECT @a, @b; END; For this example, the Oracle equivalent statements are: CREATE OR REPLACE PACKAGE root.globalPkg AS a NUMBER; b NUMBER; END globalPkg; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 405 CREATE OR REPLACE PROCEDURE root.p2 AS BEGIN globalPkg.a := 5; globalPkg.b := 5; DBMS_OUTPUT.PUT_LINE(globalPkg.a || ',' || globalPkg.b); END p2; CREATE OR REPLACE PROCEDURE root.p3 AS BEGIN globalPkg.a := globalPkg.a + 10; globalPkg.b := globalPkg.b - 5; DBMS_OUTPUT.PUT_LINE(globalPkg.a || ',' || globalPkg.b); END p3; 3.2.3 Error Handling in Stored Procedures Both Oracle PL/SQL and MySQL implement an error handling mechanism for their stored procedures. Each SQL statement in the stored procedure is checked for errors before the next statement is processed. If an error occurs, control immediately is passed to an error handler. For example, if a SELECT statement does not find any rows in the database, an error is raised, and the code to deal with this error is executed. In MySQL stored procedures, handlers can be defined to deal with errors or warnings that occurs from executing a SQL statement within a stored procedure. MySQL allows two types of handlers: CONTINUE handlers and EXIT handlers. The two types of handlers differ from their next point of execution in the stored procedure after the handler is run. For a CONTINUE handler, execution continue at the next statement after the statement that raised the error. For an EXIT handler, execution of the current compound statement, enclosed by a pair of BEGIN and END statements, is terminated and execution continues at the next statement (if any) after the compound statement. Handlers are defined to deal with one or more conditions. A condition may be a SQLSTATE value, a MySQL error code, or a predefined condition. There are three predefined conditions: SQLWARNING (warning or note), NOT FOUND (no more rows) and SQLEXCEPTION COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 406 (error). A condition may be defined separately with a name and subsequently referenced in the handler statement. All the handler definitions are made at the start of a compound statement block. In Oracle PL/SQL stored procedures, an error condition is called an exception. Exceptions may be internally defined (by the runtime system) or user-defined. Some internal exceptions have predefined name, such as ZERO_DIVIDE or NO_DATA_FOUND. Internal exceptions are implicitly (automatically) raised by the runtime system. User-defined exceptions must be given names and must be raised explicitly by RAISE statements in the stored procedures. Exception handlers handle exceptions that are raised. Exception handlers can be declared for a PL/SQL block. Such exception handlers are enclosed between BEGIN and END statements, and they handle exceptions that might be raised by statements in the PL/SQL block, including sub-blocks. A PL/SQL block is similar to a MySQL compound statement block. Exceptions can be declared only in the declarative part of a PL/SQL block, and they are local to that block and global to all of its sub-blocks. Thus, the enclosing block cannot handle exceptions raised in a sub-block if they are exceptions local to the subblock. Exceptions raised in a sub-block are not propagated to the enclosing block if exception handlers defined for sub-block handle them and if are not raised again in the exception handlers. After an exception handler runs, the current block stops executing and execution resumes at the next statement in the enclosing block. For an example of using the error handling mechanism in MySQL and Oracle stored procedures, consider the following MySQL stored procedure: CREATE PROCEDURE adjust_emp_salary () BEGIN DECLARE job_id INT; DECLARE employee_id INT DEFAULT 115; DECLARE sal_raise DECIMAL(3,2); DECLARE EXIT HANDLER FOR 1339; SELECT job_id INTO jobid FROM employees WHERE employee_id = empid; CASE WHEN jobid = 'PU_CLERK' THEN SET sal_raise := .09; WHEN jobid = 'SH_CLERK' THEN SET sal_raise := .08; COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 407 WHEN jobid = 'ST_CLERK' THEN SET sal_raise := .07; END CASE; END; The following is the Oracle PL/SQL equivalent. CREATE OR REPLACE PROCEDURE adjust_emp_salary () AS jobid employees.job_id%TYPE; empid employees.employee_id%TYPE := 115; sal_raise NUMBER(3,2); BEGIN SELECT job_id INTO jobid from employees WHERE employee_id = empid; CASE WHEN jobid = 'PU_CLERK' THEN sal_raise := .09; WHEN jobid = 'SH_CLERK' THEN sal_raise := .08; WHEN jobid = 'ST_CLERK' THEN sal_raise := .07; END CASE; EXCEPTION WHEN CASE_NOT_FOUND THEN DBMS_OUTPUT.PUT_LINE('Employee salary not adjusted.'); END; DIFFERENCES BETWEEN SQL STORED PROCEDURES AND TRIGGERS. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 408 1. When you create a trigger, you must identify an event and action of your trigger when the trigger will be executed. Stored procedures are just SQL statements that don't require an event and action. Stored procedures can be called direct from an application or within other SQL commands including other stored procedures. 2. A trigger runs automatically when the event is fired. A stored procedure is executed manually or from a caller application. 3. Within a trigger you can call stored procedures but you cannot call a trigger from a stored procedure. 4. A trigger executes implicitly whereas a stored procedure is executed via a procedure call from another block. 5. We can call a stored procedure from front end (.asp files, .aspx files, .ascx files etc.) but we can't call a trigger. 6. A stored procedure can take the input parameters, but we can't pass input parameters to a trigger. Database connection methods DATABASE CONNECTION METHODS A Database connection is a facility in computer science that allows client software to talk to database server software, whether on the same machine or not. A connection is required to send commands and receive answers, usually in the form of a result set. Connections are a key concept in data-centric programming. Since some DBMS engines require considerable time to connect, connection pooling was invented to improve performance. No command can be performed against a database without an "open and available" connection to it. Connections are built by supplying an underlying driver or provider with a connection string, which is a way of addressing a specific database or server and instance as well as user authentication credentials (for example, Server=sql_box;Database=Common;User ID=uid;Pwd=password;). Once a connection has been built it can be opened and closed at will, and properties (such as the command time-out length, or transaction, if one exists) can be set. The Connection String is composed of a set of key/value pairs as dictated by the data access interface and data provider being used. Many databases (such as PostgreSQL) only allow one operation to be performed at a time on each connection. If a request for data (a SQL Select statement) is sent to the database and a result set is returned, the connection is open but not available for other operations until the client finishes consuming the result set. Other databases, like SQL Server 2005 (and later), do not impose this limitation. However, databases that provide multiple operations per connection usually incur far more overhead than those that permit only a single operation task at a time. DATABASE CONNECTION METHODS 1. Open Database Connectivity (ODBC) COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 409 2. Java Database Connectivity (JDBC) OPEN DATABASE CONNECTIVITY Microsoft Corporation has always been ahead in introducing new technologies that positively impact the development technologies further. In the database section also, Microsoft made an effort to connect to different databases like OB2 and others which is a host- based system, dBASE, FoxPro, Paradox, and others which are a file-server OBMS2 and developing clientserver OBMS like Oraclev and others. Before Microsoft introduced Open Database Connectivity, developers had to use copyright methods to connect to a vendor’s OBMS. These methods were offered by the vendor. This requires the knowledge and expertise of the specific tools offered by the developer in order to develop an application. The disadvantage of this traditional method is that it is difficult and complex to connect multiple databases to a user-interface. Microsoft’s ODBC is a generic method to connect to any supported database. It has become phenomenally successful and is accepted and supported in the data industry. It is also one of the first few methods used to connect the user interface of the application with the back-end database. However, the speed can be reduced depending on the implementation of ODBC driver. ODBC and ODBC drivers are basically theory and its applications respectively. Open Database Connectivity is a theoretical, logical structure to connect diverse data sources. ODBC drivers are the implementations of the structure in theory. Most of them are implemented in the C language. Microsoft’s OOBC offers "maximum interoperability," and the current version 3.51 complies with XlOpen as well as the ISO call-level interface standards. Now that we have read in brief about the Microsoft’s open database connectivity, it’s time to discuss Java database connectivity. Let’s get started. STEPS IN ODBC CONNECTION When there are several databases, it is necessary to install a client tool for that database before the ODBC configuration takes place, since the ODBC driver configuration differs for each database. The ODBC configuration process for Access (.mdb) is explained below. Certain steps may differ for other database types. 1. Copy the mdb file to a folder which can be referred to from the computer where OPRO X Server is installed. 2. Setting up an ODBC data source on your workstation differs among operating systems. If the machine that you set up as your Web server is a Windows 9x machine, click Start/Settings/Control Panel. In the Control Panel, select ODBC Data Sources (32bit). If you are using Windows NT, select Start/Settings/Control Panel and select the Data Sources (ODBC) icon. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 410 If, however, your machine is using Windows 2000, you should select Start/Settings/Control Panel and choose the Administrative Tools icon. Within the Administrative Tools window, choose the Data Sources (ODBC) icon. 3. Choose the System DSN tab from the ODBC Data Source Administrator dialog box, shown in Figure 1, and click the Add button. The System DSN tab allows you to create a data source that can be shared on the Internet. Using a System DSN Caution: To make a database available to your Web page visitors, you must create the ODBC source under the System DSN tab. 4. Select the Microsoft Access driver and click Finish. 5. In the ODBC Microsoft Access Setup dialog box, shown in Figure 2, type the name you wish to use for your data source name in the Data Source Name field. 6. In the Database panel of the ODBC Microsoft Access Setup dialog box, click the Select button. 7. Navigate to the location of your database on your Web server and click OK. 8. Click the Options>> button located in the lower-right corner of the ODBC Microsoft Access Setup dialog box. In the Page Timeout field, type 5000. Changing the Default Page Timeout Caution: It is especially important that you change the default page timeout setting if you are using Windows 2000 as your Web server and an Access database. Failing to change this value can result in permission problems when accessing database-driven Web pages. For more information on this potential problem, visit http://www.macromedia.com/support/ultradev/ts/documents/80004005_win2k_error.htm. 9. Click OK to close the ODBC Microsoft Access Setup dialog box. 10. As shown in Figure 3, the ODBC Data Source Administrator dialog box now shows a data source for your database. JAVA DATABASE CONNECTIVITY Java Database Connectivity, popularly known as JDBC, is a Java API that is used to connect and execute queries with the help of database. JDBC is a part of JavaSE, an acronym for Java Standard Edition. JDBC drivers, which are used to connect with the database, are of four types. There is a JDBC-ODBC Bridge Driver, Native Driver, Network Protocol Driver, and Thin Driver. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 411 The JDBC API accesses tabular data stored in relational databases. In these databases, data can be saved, updated, deleted and fetched also. It is very similar to Microsoft’s Open Database Connectivity, also known as ODBC, the one we discussed earlier. Java Database Connectivity is based on the Open SQL Call Level Interface and the java.sql package contains classes and interfaces for JDBC API. Some widely used interfaces of JDBC API include the Driver interface, Connection interface, Statement interface, CallableStatement interface, ResultSet interface among others. Whereas, some popular JDBC API classes are DriverManager class, Blob class, Clob class, Types class etc. JDBC has a huge advantage over Open Database Connectivity (which was hugely popular before the advent of JDBC). One issue with ODBC is that ODBC API (application programming interface) uses its drivers which are primarily written in C language and hence it is not platform independent and is not as secure. Java came up with a solution and hence developed its own API which is known as the JDBC API. These APIs uses JDBC drivers which are programmed in the Java language. JDBC API can connect to the database, execute queries and update statements to the database, retrieve the results received from the database with the help of a Java program. 5 STEPS TO CONNECT TO THE DATABASE IN JAVA There are 5 steps to connect any java application with the database using JDBC. These steps are as follows: 1. Register the driver class 2. Create the connection object 3. Create the Statement object 4. Execute the query 5. Close the connection object 1) Register the driver class The forName() method of Class class is used to register the driver class. This method is used to dynamically load the driver class. Syntax of forName() method 1. public static void forName(String className)throws ClassNotFoundException Note: Since JDBC 4.0, explicitly registering the driver is optional. We just need to put vender's Jar in the classpath, and then JDBC driver manager can detect and load the driver automatically. Example to register the OracleDriver class Here, Java program is loading oracle driver to esteblish database connection. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 412 1. Class.forName("oracle.jdbc.driver.OracleDriver"); 2) Create the connection object The getConnection() method of DriverManager class is used to establish connection with the database. Syntax of getConnection() method 1. 1) public static Connection getConnection(String url)throws SQLException 2. 2) public static Connection getConnection(String url,String name,String password) 3. throws SQLException Example to establish connection with the Oracle database 1. Connection con=DriverManager.getConnection( 2. "jdbc:oracle:thin:@localhost:1521:xe","system","password"); 3) Create the Statement object The createStatement() method of Connection interface is used to create statement. The object of statement is responsible to execute queries with the database. Syntax of createStatement() method 1. public Statement createStatement()throws SQLException Example to create the statement object 1. Statement stmt=con.createStatement(); 4) Execute the query The executeQuery() method of Statement interface is used to execute queries to the database. This method returns the object of ResultSet that can be used to get all the records of a table. Syntax of executeQuery() method 1. public ResultSet executeQuery(String sql)throws SQLException Example to execute query 1. ResultSet rs=stmt.executeQuery("select * from emp"); COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 413 2. 3. while(rs.next()){ 4. System.out.println(rs.getInt(1)+" "+rs.getString(2)); 5. } 5) Close the connection object By closing connection object statement and ResultSet will be closed automatically. The close() method of Connection interface is used to close the connection. Syntax of close() method 1. public void close()throws SQLException Example to close connection 1. con.close(); Note: Since Java 7, JDBC has ability to use try-with-resources statement to automatically close resources of type Connection, ResultSet, and Statement. It avoids explicit connection closing step. VERIFYING THE CONNECTION After setting the JDBC, and ODBC connections as specified above, the OPRO X Server should be started. If the database connection is successful, a message will be printed in the Access.log and if the connection failed, the message is printed in the Error.log. * The default location where the Access.log and Error.log are created is; [ OXS_HOME ] /logs/ folder. The folder which contains the log files is specified by the ODCAW/COMMON/LOG/ element of ODCAW.xml file. REPORTS COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 414 UNIT 5 VERIFICATION AND SYSTEMS TESTING Database testing DATABASE TESTING Database Testing is testing, which is used to analyze the schema, tables, triggers, etc., of the database under test. It also assesses data integrity and consistency, which might include creating difficult queries to load and stress test the Database and review its responsiveness. Generally, it contains the layered process, which involves the data access, User Interface [UI], the business layer, along with the database layer. Why do we need to perform database testing? If we performed the database testing, it would ensure the database's efficiency, maximum stability, performance, and security. And these features can be set aside on a check occasionally to confirm that the software application is stable as soon as deployed in a competitive environment. To perform database testing, we must have a basic knowledge of SQL. PURPOSE OF THE DATABASE TESTING The main objective of performing database testing is to make sure they follow the various aspects: • Transaction's ACID Properties • Data mapping • Accuracy of Business Rule • Data integrity 1. Transaction's ACID Properties The database testing will ensure the ACID properties of the transaction. A Database performs these four ACID properties. The ACID properties are as follows: • Atomicity • Consistency • Isolation • Durability Atomicity COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 415 • The term atomicity in transaction specifics that the data remains atomic, which implies that if any operation is performed on the data, it should be performed or implemented entirely or should not be implemented at all. • It is also known as All-or-Nothing. Consistency • The term consistency specifies that the value should remain always preserved after the transaction is completed in the transaction. • And the integrity of the data is very important therefore, the database remains consistent before and after the transaction. The data should always be correct. Isolation • In the transaction, the term isolation means separation, which specified that the multiple transactions could implement all at once without impacting one another and changing the database state. • Or if two or more transactions occur concurrently, the consistency should remain preserved. Durability • The word durability makes sure the permanency of something, which further implies if a transaction is committed, it will keep the modifications without any fail irrespective of the effect of external factors. • And the durability of the data should be so faultless even though the system fails, the database still survives. 2. Data Mapping Data mapping is an essential feature in database testing, which is mainly focused on verifying the data that pass through back and out between the application and the backend database. Below are some of the important features tested in the data mapping: • We analyze whether the user interface or front-end methods are mapped constantly with the equivalent fields in the database table. • Characteristically, this mapping information is specified in the requirements documents. • When a specific action is done at the front-end of an application, an equivalent Create, Retrieve, Update and Delete [CRUD] activity gets used at the back-end. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 416 • And then, the test engineer will have to assess if the correct activity is used and whether the user action in itself is effective or not. 3. The Accuracy of the Business Rules • Database testing ensures the accuracy of the business rules as we know that complex databases lead to complex components such as stored procedure triggers and relational constraints. • Therefore, the test engineer will come up with appropriate SQL commands to verify the complex objects. 4. Data Integrity • The database testing also makes sure the data integrity, where we can update, and the most recent shared data values should appear on all the forms and screens. • And if the value should not be modified on one screen and show an older value on another, then the status can be updated concurrently. HOW TO PERFORM DATABASE TESTING We can perform the database testing either manually or with the help of some automation tools. PERFORMING DATABASE TESTING MANUALLY To perform database testing manually, which need to follow the below process: • Firstly, we will Open the SQL server in our local system. • After that, we will open the query analyzer to write the command and retrieve the data. • Once we can retrieve the specified data, we will compare the detailed data with the expected result. • Then we can update or delete the data to check how the software application performs. • The general test process of the testing database is not dissimilar from any other application. Therefore, to run the test, we can follow the below steps: Step1: Set up the test environment Firstly, we need to prepare the test environment to test the software application. Step2: Execute the test Once we set up the test environment, we will run particular test case. Step3: Check the results COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 417 When the test case is executed successfully without having any issues, we will check the specified test case results. Step4: Validate the output with the expected one After checking the test case result, we will validate the same output with the excepted one. If the Page | 418 results meet the excepted output, the test case will consider as a pass; otherwise, it will be marked as a fail. Step5: Report the results to the stakeholders And at last, we will report the results to the stakeholder of the particular software application. Note: If we set-up the environment, the test engineer and developers will develop all possible scenarios, which can execute through the application. Then, the test will involve running through these queries and checking the data integrity, which means that the resulting data will need to be truthful, accurate, complete, retrievable, and verifiable. And the test could also include monitoring data mapping, the different ACID properties, and ensuring the implemented business rules' accuracy. HOW AUTOMATION CAN HELP IN DATABASE TESTING In software testing, Automation testing is used to decrease the repetitive manual work, which helps the test engineer focus more on critical features, which work the same for the database testing. Let's see a few scenarios where automation can be very useful for the test engineer: • Modification in the database schema When every schema is modified, the database needs in-depth testing to ensure that the things are in place. And the number of scenarios to be covered based on the size of the database. And this process is time-consuming if we have done it manually. • Monitoring for data integrity issues There can be a condition where a set of data gets corrupted in recovery or other actions because of human error or other issues. But if we consider the automated monitoring processes, it became easier to find those variations, and we can fix them as soon as possible. • New or frequently altering applications As we know that Agile methodology is the new era of testing, where we will have a new release to production at the end of every sprint, which implies it will take every 2-3 weeks to complete one round of testing. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) But with the help of automation features, which is completely constant and unchanged in the recent sprint, we can focus on new modified requirements. DATABASE TESTING COMPONENTS Following are the components of the database testing: • Database schema • Transactions • Store procedure • Field constraints • Triggers 1. Database Schema A database schema is used to describe the working of data in a Database and its organization. In other words, we can say that it is nothing but a proper classification of how the data will be planned inside the database. For testing those conditions, we have two ways, which are explained below: One of the Below approaches can be used as per the tool's significance: • We can use the SchemaCrawler tool, which is a free database schema discovery and comprehension tool. • Regular expressions are a good approach to verify the names of the specific fields and their values. • To verify the schema, we can use the following SQL command: 1. DESC<table name> Find the needs according to the Database operates • The Field names begin or end with explicit characters. • The Primary keys need to be generated before any other fields are designed. • The specific values can or cannot be inserted in the fields that have a constraint. • For easy recovery and search, the Foreign keys must be indexed completely. 2. Transactions One of the most important database testing components is transactions because while we are performing the database testing, the ACID properties need to satisfy. • The most commonly used statements are as below: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 419 1. BEGIN TRANSACTIONTRANSACTION# 2. END TRANSACTIONTRANSACTION# • To make sure the database remains in a consistent state, we can use the below ROLLBACK commands: 1. ROLLBACK TRANSACTION# • To ensure the modification have been reproduced, we can use a SELECT command after the implementation of the above command: 1. SELECT * FROM TABLENAME < Transactions Tables > Note: In the above statement, the Transaction table is the table that includes the transaction. 3. Stored Procedure The Stored Procedures are relatively parallel to user-defined functions. And the entire system works in looming with the most consistent and correct result. It can be used by Execute or Call Procedure commands, and generally, the output is in the format of result sets. The stored procedure system is used for multiple applications where data is kept in RDBMS. We can test the stored procedure throughout the white-box and black-box testing. • White box testing: In white box testing, the Stubs are used to invoke the stored procedures and then the output is verified in contradiction of the expected values. • Black box testing: In this, we can operate the application's front-end (UI). And also assess the implementation of the stored procedure and its outputs. 4. Field Constraints The next database testing components are Field Constraints, where the entire system works on the default value, exclusive value, and foreign key. In this, we can easily verify the outcomes retrieved from the SQL commands, and to ensure that the object condition in the database is implemented, we can perform the Front-end (user interface) operations. 5. Triggers The trigger components are used to implement an entire table independently to record the output. In other words, we can say that a trigger (a piece of code) can be auto-instructed to be performed if a particular event takes place on a precise table. Let us see one sample example, where we can understand the working of trigger components in the database testing: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 420 • Suppose a new employee joined a company. And the employee is doing two tasks, which are development and testing. Then the employee is added to the Employee table. • Once he/she is added to the Employee table, a Trigger could add the employee to the equivalent task's • After that, we can follow the common process to test it, firstly the SQL command implanted in the Trigger independently and then it records the result. • In the end, we can follow this process to perform the trigger as an entire system and then compare the outcomes. These types of tests are completed in two ways, which are as follows • White-Box Testing • Black-Box Testing Both the white-box and black-box testing have their procedure and sets of rules, which help us get the precise result. TYPES OF DATABASE TESTING The database testing classified into three different types of testing, which are as follows: • Structural testing • Functional testing • Non-functional testing Structural Database Testing • It is a most important database testing technique used to verify all the elements inside the data repository, which are primarily used for data storage and not allowed to be directly operated by end-users. • If we want a successful conclusion of this testing, we must have a complete understanding of SQL commands. • In structural database testing, we can test the database components that are not visible to users. • The structural database testing is mostly vitally used to validate the database. Functional Database Testing • The most important database testing approach is functional database testing, which is used to authorize a database's functional requirements from the end user's interpretation. • The functional database testing's primary purpose is to test whether the end-user's transactions and operations are connected to the database work as expected or not. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 421 Non-functional Testing In the topic of database testing, Non-functional testing can be divided into several types as vital by the business requirements. Some of the important parts of non-functional testing are listed below: • Load testing • Stress Testing • Security Testing • Usability Testing • Compatibility Testing Note: The load testing and the stress testing come under Performance Testing, which helps two specific non-functional testing objectives. CHALLENGES OF DATABASE TESTING While performing database testing, we may encounter the following challenges. In the below table, we listed some common challenges and their solutions: DIFFERENT CHALLENGES Testing huge data and production simulated the database Re-usability of data again for testing and Test data creation Separation of data and queries SOLUTIONS o A scaled-down or enhanced database would be the best solution because it is as close as possible to the production data set. o Although it is a good approach to test in a production-like environment, it could sometimes become a very challenging and time-consuming process to test on enormous data. o To resolve this specific issue, we need a better strategy to generate all the essential data for all the stretch repetitions. And then, we can use detailed data carefully. o All the commands need to be separate from each other; for example, the input data and output of one command do not modify another command's output. o The software product quality depends on the cost. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 422 Cost and time were taken to get the data from a massive database o Therefore, it is significant to maintain a balance between the project timelines, expected quality and data load, and additional factors. Frequently altering the database structure o While performing DB testing, the Database test engineers most frequently faced this challenge. o The best solution for the particular challenges is that the DB tester needs to create the test cases and the SQL command derived from the specific structure, which gets modified at the time of implementation or through any other retesting. o To avoid the final delays, we need to intercept the modification and the impact as early as possible. o The best solution for unwanted data modification in DB testing is access control. o We can provide access only to a limited number of people for the modification. o And the access should be restricted for the EDIT and DELETE options. Unwanted data modification MISCONCEPTION OR MYTHS RELATED TO DATABASE TESTING When we are performing the database testing, we may undergo some misconceptions about database testing. Let us see them one by one and also understand the reality of the related myths: MISCONCEPTION OR MYTHS REALITY The overall development process will slow down because of the database testing. For this particular myth, the reality is that database testing helps us enhance the database application's overall quality. Database Testing is a monotonous In software testing, database testing is an efficient job, and it involves plenty of process, which gives long-term functional expertise. stability to the entire application. Database testing is an expensive process. Expenses on Database Testing is needed because any expenses on database testing is a long-term investment that leads to long-term robustness and constancy of the application. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 423 Database testing increases additional work for bottlenecks. In reverse, identifying the hidden defects with the help of database testing enhances more value to the overall work. AUTOMATION TOOLS USED IN DATABASE TESTING We have several Database testing tools available in the market, but here we are discussing some of the most commonly used automation tools for database testing, which are as follows: • Data factory • SQL test • Mockup data • MS SQL Server • DbUnit Data Factory • The data factory is one of the most popular tools used for database testing. • Mostly it is used for commercial database testing tools, which means that the huge project can be tested by a data factory tool. • It works as a data generator and data manager in the context of database testing. • For handling the complex command with a large amount of data, it is the most efficient tool. • This tool gives us a platform to easily perform the stress or load testing on the database. SQL Test • The SQL test is the most frequently used Database testing tool available in the market. • It is an open-source tool tSQLt framework, which means that it can be used by all the Database test engineer at least once. • It allows us to execute the unit tests for SQL Server databases. • With the help of this tool, we can easily execute extensive SQL tests. • The major drawback of this tool is that it is slow compared to the other Database testing tools in the market. Mockup data • The Mockup Data testing tool also comes under the Test Data Generator category, and it is commercial testing tool. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 424 • In this tool, we need to add columns in our table to validate the outputs. • It helps us to create a huge Amount of Data, CSV files and databases with accurate data. • It rapidly creates a large amount of data and tests several tables for a relationship with foreign keys. MS SQL Server • The Microsoft SQL server tool is extensively used to execute the unit testing. • It is a commercial tool where we can generate in VB or C# projects, and the test engineer is expected to understand the project schema before starting the test. • Even though we are creating the tests from a database project, we can use SQL Server Object Explorer. • The main disadvantage of this tool is that it does not have any good user interface. DbUnit • It is an open-source tool, which is also known as the JUnit extension. • It helps us export and import data into a database to and from XML datasets and work on large databases. • It performs the CLEAN-INSERT operation initially; that's why it does not perform any further clean-up. • With the DBUnit tool's help, we can explore the data and connect relational and multidimensional databases. Unit testing UNIT TESTING Historically, if you asked what unit testing was, you’d probably get a curious mix of definitions. This has included everything from very specific definitions, like, “Unit testing is the process of writing code to test the behavior and functionality of your system,” to the extremely vague: “It’s when you test the stuff you just did.” But the one thing you’ll probably get everybody to agree on is that, whatever unit testing is, everyone should be doing more of it. Unit testing is the flossing of the technical world: If we don’t do it, we should start; and if we already do it, we don’t do it enough! UNIT TESTING BASICS A unit test is an automated test, generally written by a software developer, that isolates a granular component of code and tests it independently. Consider a simple example. Let’s say that we write a method, Add(int x, int y), that adds two integers. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 425 A unit test of this method would mean calling Add(2, 2) and subsequently verifying that the result is 4. We might then write another unit test of Add(2, -2) and verify that the result is zero.. PROPERTIES OF UNIT TESTS • Unit tests are automated. A unit test framework executes the verification and returns a pass/fail verdict. • Unit tests are granular. That Add() function is just a tiny cog in the overall application, but we test it individually. • Unit tests isolate their target. We don’t need to set up a bunch of application settings, files, or global variables to test Add(). • Unit tests are deterministic. Add(2, 2) returns 4 every single time it’s run, predictably and repeatedly. • Unit tests are independent. They don’t depend on the prior execution of any other unit tests or have any concept of sequential ordering. Unit tests need to follow certain guidelines and need to be maintainable. Here are five elements of good, maintainable unit tests. WHY TO UNIT TEST YOUR DATABASE Your database is a critical part of your overall application. It shouldn’t be a testing blind spot. If the application code opens a file or connects to a database, that violates the principles of granularity, isolation, and determinism. So you mock those things out and omit them from your unit test suite. How, then, do you test them? Well, that’s what integration testing is for. You pay special attention to every nook and cranny of your application code, and then you slam all databaserelated testing concerns under the general heading of integration testing. But don’t your databases count? Aren’t they part of your technical work product? Don’t they deserve unit testing as well? While unit testing a database might not be as common or familiar as unit testing application code, it’s perfectly achievable! Let’s see how. HOW TO UNIT TEST YOUR DATABASE Your source-controlling the creation scripts for the various tables, views, triggers, sprocs, etc., in your database. Conceptually, this gives you the ability to take a blank database instance and create a minimum subset of these factors in isolation. From there, you can test all sorts of incremental behaviors. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 426 • Write a script that will wipe out the database before you start unit tests, then populate the database with a predefined set of data and run the tests. You can also do that before every test; it’ll be slow but less error-prone. • Ensure that the database is in a known state before each test runs, and verify the state after the run using assertions logic. • You can also look for problems like missing references that can happen due to accidentally removing or renaming objects, like columns that are still being referenced by a module such as a view. • In the end, make sure that the database is restored to its original state after the test execution. Now, databases are inherently different in some key ways from application code. You have to take some steps, like placing increased emphasis on putting the database into known states and making sure that each individual developer has a copy of the database server. But the leap isn’t as big as you might think. TOOLS TO USE Just as you wouldn’t write your own application unit testing framework because plenty of these already exists, the same holds true with database unit testing frameworks, even if they’re not as well known. Here are a handful of tools to check out to kick-start your research. DbUnit SQL Server SQL Test DbFit DB Test Driven DbUnit puts your database into known states between tests. DbUnit is a JUnit extension useful for database-driven projects. You can import and export your database data as well as verify if your data matches a specified set. SQL Server supports database unit testing as a part of its feature suite. You can create a test project and add a SQL Server unit test directly that you can then work on. SQL Test is another tool where the database unit tests run in transactions. It later rolls back any changes, so you won’t need any cleanup code. It uses the open-source tSQLt framework. With DbFit, you can perform test-driven database development. You can write readable and manageable unit tests for your database code. DBTD is a tool for database test-driven development that, along with helping you create database unit tests that are easy to manage, also gives you code COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 427 coverage. It also integrates with build servers for continuous integration capabilities. Integration testing INTEGRATION TESTING Integration testing (sometimes called integration and testing, abbreviated I&T) is the phase in software testing in which individual software modules are combined and tested as a group. Integration testing is conducted to evaluate the compliance of a system or component with specified functional requirements. It occurs after unit testing and before validation testing. Integration testing takes as its input modules that have been unit tested, groups them in larger aggregates, applies tests defined in an integration test plan to those aggregates, and delivers as its output the integrated system ready for system testing. Why do Integration Testing? Although each software module is unit tested, defects still exist for various reasons like • A Module, in general, is designed by an individual software developer whose understanding and programming logic may differ from other programmers. Integration Testing becomes necessary to verify the software modules work in unity • At the time of module development, there are wide chances of change in requirements by the clients. These new requirements may not be unit tested and hence system integration Testing becomes necessary. • Interfaces of the software modules with the database could be erroneous • External Hardware interfaces, if any, could be erroneous • Inadequate exception handling could cause issues. EXAMPLE OF INTEGRATION TEST CASE Integration Test Case differs from other test cases in the sense it focuses mainly on the interfaces & flow of data/information between the modules. Here priority is to be given for the integrating links rather than the unit functions which are already tested. Sample Integration Test Cases for the following scenario: Application has 3 modules say ‘Login Page’, ‘Mailbox’ and ‘Delete emails’ and each of them is integrated logically. Here do not concentrate much on the Login Page testing as it’s already been done in Unit Testing. But check how it’s linked to the Mail Box Page. Similarly Mail Box: Check its integration to the Delete Mails Module. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 428 Test Case ID Test Case Objective Test Case Description Expected Result 1 Check the interface link between the Login and Mailbox module Enter login credentials and click on the Login button To be directed to the Mail Box Check the interface link between the Mailbox and Delete Mails Module From Mailbox select the email and click a delete button Selected email should appear in the Deleted/Trash folder 2 APPROACHES, STRATEGIES, TYPES, METHODOLOGIES OF INTEGRATION TESTING Software Engineering defines variety of strategies to execute Integration testing, viz. • Big Bang Approach: • Incremental Approach: which is further divided into the following • Top Down Approach • Bottom Up Approach • Sandwich Approach – Combination of Top Down and Bottom Up Below are the different strategies, the way they are executed and their limitations as well advantages. Big Bang Testing Big Bang Testing is an Integration testing approach in which all the components or modules are integrated together at once and then tested as a unit. This combined set of components is considered as an entity while testing. If all of the components in the unit are not completed, the integration process will not execute. Advantages: • Convenient for small systems. Disadvantages: • Fault Localization is difficult. • Given the sheer number of interfaces that need to be tested in this approach, some interfaces link to be tested could be missed easily. • Since the Integration testing can commence only after “all” the modules are designed, the testing team will have less time for execution in the testing phase. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 429 • Since all modules are tested at once, high-risk critical modules are not isolated and tested on priority. Peripheral modules which deal with user interfaces are also not isolated and tested on priority. Incremental Testing In the Incremental Testing approach, testing is done by integrating two or more modules that are logically related to each other and then tested for proper functioning of the application. Then the other related modules are integrated incrementally and the process continues until all the logically related modules are integrated and tested successfully. Incremental Approach, in turn, is carried out by two different Methods: • Bottom Up • Top Down Stubs and Drivers Stubs and Drivers are the dummy programs in Integration testing used to facilitate the software testing activity. These programs act as a substitutes for the missing models in the testing. They do not implement the entire programming logic of the software module but they simulate data communication with the calling module while testing. Stub: Is called by the Module under Test. Driver: Calls the Module to be tested. Bottom-up Integration Testing Bottom-up Integration Testing is a strategy in which the lower level modules are tested first. These tested modules are then further used to facilitate the testing of higher level modules. The process continues until all modules at top level are tested. Once the lower level modules are tested and integrated, then the next level of modules are formed. Diagrammatic Representation: COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 430 Advantages: • Fault localization is easier. • No time is wasted waiting for all modules to be developed unlike Big-bang approach Disadvantages: • Critical modules (at the top level of software architecture) which control the flow of application are tested last and may be prone to defects. • An early prototype is not possible Top-down Integration Testing Top Down Integration Testing is a method in which integration testing takes place from top to bottom following the control flow of software system. The higher level modules are tested first and then lower level modules are tested and integrated in order to check the software functionality. Stubs are used for testing if some modules are not ready. Advantages: • Fault Localization is easier. • Possibility to obtain an early prototype. • Critical Modules are tested on priority; major design flaws could be found and fixed first. Disadvantages: • Needs many Stubs. • Modules at a lower level are tested inadequately. Sandwich Testing Sandwich Testing is a strategy in which top level modules are tested with lower level modules at the same time lower modules are integrated with top modules and tested as a system. It is a combination of Top-down and Bottom-up approaches therefore it is called Hybrid Integration Testing. It makes use of both stubs as well as drivers. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 431 Page | 432 How to do Integration Testing? The Integration test procedure irrespective of the Software testing strategies (discussed above): 1. Prepare the Integration Tests Plan 2. Design the Test Scenarios, Cases, and Scripts. 3. Executing the test Cases followed by reporting the defects. 4. Tracking & re-testing the defects. 5. Steps 3 and 4 are repeated until the completion of Integration is successful. Brief Description of Integration Test Plans: It includes the following attributes: • Methods/Approaches to testing (as discussed above). • Scopes and Out of Scopes Items of Integration Testing. • Roles and Responsibilities. • Pre-requisites for Integration testing. • Testing environment. • Risk and Mitigation Plans. Entry and Exit Criteria of Integration Testing Entry and Exit Criteria to Integration testing phase in any software development model Entry Criteria: • Unit Tested Components/Modules • All High prioritized bugs fixed and closed COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) • All Modules to be code completed and integrated successfully. • Integration tests Plan, test case, scenarios to be signed off and documented. • Required Test Environment to be set up for Integration testing Exit Criteria: • Successful Testing of Integrated Application. • Executed Test Cases are documented • All High prioritized bugs fixed and closed • Technical documents to be submitted followed by release Notes. Best Practices/ Guidelines for Integration Testing • First, determine the Integration Test Strategy that could be adopted and later prepare the test cases and test data accordingly. • Study the Architecture design of the Application and identify the Critical Modules. These need to be tested on priority. • Obtain the interface designs from the Architectural team and create test cases to verify all of the interfaces in detail. Interface to database/external hardware/software application must be tested in detail. • After the test cases, it’s the test data which plays the critical role. • Always have the mock data prepared, prior to executing. Do not select test data while executing the test cases. DIFFERENCES BETWEEN INTEGRATION AND UNIT TESTING Integration testing and unit testing are two levels of software testing, where a unit is the basic one and integration is the sequential one. Unit testing implies checking the smallest functioning parts of code separately. Integration testing goes further: we look for errors that happen when units start interacting. The fact that units have successfully passed the tests at the previous stages doesn’t guarantee that they will work well together. Therefore, any problems arising when we assemble several smaller parts into a subsystem can be associated with the particularities of the interaction between these units. The earlier we notice something abnormal, the lower will be the cost of a mistake. Unit testing is the initial stage of the QA process. It prepares the functionality to the following stage which is integration testing. Without passing the former and verifying that units perform correctly, we cannot proceed to the latter and start putting them together. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 433 If integration testing is the first chapter of the story (or the pilot of a TV show), unit testing is a prequel. As a rule, software engineers run unit testing at the earlier stages of product development. To wrap it up, unit testing is the examination of the smallest functional parts of code. Integration testing is the examination of the smallest possible combinations of those parts. Page | 434 BENEFITS OF INTEGRATION TESTING Integration testing allows dividing code into blocks that consist of several units and check the parts of software gradually before assembling them all into a complete system. It means that all the systems will be properly revised, regardless of when, how, and why they have been created. Verification of software integrity is essential since only functional and highly-performing builds should be allowed to proceed to the further stages of testing. Otherwise, finding bugs will become more difficult and take more time. If you need to outline the advantages of the integration testing in a nutshell, here they are: • Simultaneous testing of different modules is very convenient, practical, and costefficient. • Integration checks can take place at any stage of the SDLC. • It is a lifesaver for a team involved in projects with constantly changing requirements or logic that is under review after development has started. • Unlike other types of tests, integration can cover any amount of program code in one sprint (thanks to the different approaches we’ll explain in the following section). CHALLENGES OF INTEGRATION TESTING We’ve told a lot about how integration testing works and what advantages it brings. As usual, benefits come with some challenges. There are several factors that can make integration testing more complicated than you expect. Here are some examples of such situations: • If too many people participate in code writing, and each has a different style, it makes it difficult to understand the logic of units. • A combination of diverse factors (databases, platform, environment, etc.) can complicate the testing. • Integrating two legacy systems is rarely seamless, as well as integrating a new system into the existing one. • If a system meant for integration are developed by different teams, they can be incompatible. • Different approaches and testing combinations can make it difficult to choose the most efficient model. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) HOW TO DO INTEGRATION TESTING There is a simple algorithm a QA team can apply to run integration tests. Here is what the sequence of our actions typically looks like: 1. Write a test plan. 2. Create test cases and use cases. 3. Run tests after unit integration. 4. Detect errors. 5. Retest the functionality after bug fixing. 6. Repeat the testing cycle until all bugs are fixed. There are two criteria that allow a QA team to conduct effective testing. And by effective testing, we mean detection of all the defects and shortcomings. So, testers should: 1. Understand product structure and be aware of how units interact. 2. Be familiar with project peculiarities to be able to write good test cases, analyze the results correctly, and choosing between manual and automated testing. INTEGRATION TESTING EXAMPLE Let’s say, you have a fitness app with personalized training and meal plans. We won’t go into details regarding functionality. The core features of a similar app are: • signing up / logging in the system; • viewing available workouts and meals; • choosing a personalized plan; • tracking the progress. At the initial stages of product testing, the team develops user registration and authorization logic. These are pages with forms for entering login and password or signing in via social media accounts. After passing verification successfully, a first-time user should be redirected to the page that requests entering certain personal parameters for customization. If the flow appears to be different, there is an error in the system. To find and fix this bug, we run integration tests. INTEGRATION TESTING TOOLS • Jasmine – a tool that uses JavaScript frameworks, simple syntax, runs on all browsers and is perfect for testing JavaScript code. • VectorCAST – simple and transparent technology used for testing important business systems. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 435 • FitNesse – an open-source project that supports all major languages, highly adaptable, and doesn’t require an additional installation. These are only some of the widely used tools you can see on the majority of popular lists. There are also Rational Integration Tester, Protractor, Selenium, and many more programs that simplify integration testing and boost its efficiency. Page | 436 The choice of a tool depends on the programming language, payment options, project specifications, and tester’s preferences. INTEGRATION TESTING TIPS • Always study software architecture and app design to prioritize the units and their combinations correctly. • Always have a clear integration test strategy with test cases and test data outlined in it. The information should be easy to understand to all members of a QA team. • Write test cases to cover all interface features. It should be a precise examination since the interface is the point of user interaction. • Don’t select test data on the go. Prepare the mock data before you proceed to actual tests. • Keep project documentation handy. Approach developers with questions regarding the functionality if something is not mentioned in the documents or is poorly described. • Make sure the development team has checked all the modules properly before handling software for you. • Don’t neglect automation. It can be a real time-saver and deliver more accurate results. Debugging. DEBUGGING Debugging, in computer programming and engineering, is a multistep process that involves identifying a problem, isolating the source of the problem, and then either correcting the problem or determining a way to work around it. The final step of debugging is to test the correction or workaround and make sure it works. In software development, the debugging process begins when a developer locates a code error in a computer program and is able to reproduce it. Debugging is part of the software testing process and is an integral part of the entire software development lifecycle. In hardware development, the debugging process typically looks for hardware components that are not installed or configured correctly. For example, an engineer might run a JTAG connection test to debug connections on an integrated circuit. HOW DEBUGGING WORKS IN SOFTWARE COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Typically, the debugging process starts as soon as code is written and continues in successive stages as code is combined with other units of programming to form a software product. In a large program that has thousands and thousands of lines of code, the debugging process can be made easier by using strategies such as unit tests, code reviews and pair programming. To identify bugs, it can be useful to look at the code's logging and use a stand-alone debugger Page | 437 tool or the debug mode of an integrated development environment (IDE). It can be helpful at this point if the developer is familiar with standard error messages. If developers aren't commenting adequately when writing code, however, even the cleanest code can be a challenge for someone to debug. In some cases, the module that presents the problem is obvious, while the line of code itself is not. In that case, unit tests -- such as JUnit and xUnit, which allow the programmer to run a specific function with specific inputs -- can be helpful in debugging. The standard practice is to set up a "breakpoint" and run the program until that breakpoint, at which time program execution stops. The debugger component of an IDE typically provides the programmer with the capability to view memory and see variables, run the program to the next breakpoint, execute just the next line of code, and, in some cases, change the value of variables or even change the contents of the line of code about to be executed. IMPORTANCE OF DEBUGGING Debugging is an important part of determining why an operating system, application or program is misbehaving. Even if developers use the same coding standard, it's more than likely that a new software program will still have bugs. In many cases, the process of debugging a new software program can take more time than it took to write the program. Invariably, the bugs in software components that get the most use are found and fixed first. DEBUGGING VS. TESTING Debugging and testing are complementary processes. The purpose of testing is to identify what happens when there is a mistake in a program's source code. The purpose of debugging is to locate and fix the mistake. The testing process does not help the developer figure out what the coding mistake is -- it simply reveals what effects the coding error has on the program. Once the mistake has been error identified, debugging helps the developer determine the cause of the error so it can be fixed. Examples Some examples of common coding errors include the following: • Syntax error • Runtime error • Semantic error • Logic error COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) • Disregarding adopted conventions in the coding standard • Calling the wrong function • Using the wrong variable name in the wrong place • Failing to initialize a variable when absolutely required • Skipping a check for an error return DEBUGGING STRATEGIES Source code analyzers, which include security, common code errors and complexity analyzers, can be helpful in debugging. A complexity analyzer can find modules that are so intricate as to be hard to understand and test. Other debugging strategies include the following: • Static analysis -- the developer examines the code without executing the program. • Print debugging (also called tracing) -- the developer watches live or recorded print statements and monitors flow. • Remote debugging -- the developer's debugger runs on a different system than the program that is being debugged. • Post-mortem debugging -- the developer only stops to debug the program if it experiences fatal exceptions. DEBUGGING TOOLS A debugger is a software tool that can help the software development process by identifying coding errors at various stages of the operating system or application development. Some debuggers will analyze a test run to see what lines of code were not executed. Other debugging tools provide simulators that allow the programmer to model how an app will display and behave on a given operating system or computing device. Many open source debugging tools and scripting languages do not run in an IDE, so they require a more manual approach to debugging. For example, USB Debugging allows an Android device to communicate with a computer running the Android SDK. In this situation, the developer might debug a program by dropping values to a log, creating extensive print statements to monitor code execution or implement hard-coded wait commands that will simulate a breakpoint by waiting for keyboard input at specific intervals. CHALLENGES OF DEBUGGING The debugging process can be quite difficult and require as much work -- if not more -- than writing the code to begin with. The process can be especially challenging when: • The negative effect of the coding error is clear, but the cause is not. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 438 • The negative effect of the coding error is difficult to reproduce -- for example when web content contains drop down menus. • Dependencies are not clear, so fixing a coding error in one part of the program accidentally introduces new errors in other parts of the program. HISTORY OF DEBUGGING The use of the word bug as a synonym for error originated in engineering. The term's application to computing and the inspiration for using the word debugging as a synonym for troubleshooting has been attributed to Admiral Grace Hopper, a pioneer in computer programming, who was also known for her dry sense of humor. When an actual bug (a moth) got caught between electrical relays and caused a problem in the U.S. Navy's first computer, Admiral Hopper and her team "debugged" the computer and saved the moth. It now resides in the Smithsonian Museum. COMPILED BY WWTL STUDENTS (PKCE, ACCE, AMCE) Page | 439