You are on page 1of 165

BSIT 61 Basics of .

NET

Introduction

By the end of this introductory section, you will know 8 8 8 8 8 New platform - .NET Scope of this book Significance of .NET C# and .NET System Requirements

A New Platform .NET


In the recent years there is an emerging demand and interest among the software designers to implement the applications independent of the hardware, operating system and language. Microsoft made a successful effort to provide a platform for advanced complex applications to be developed easily. Microsoft .NET framework provides an efficient way to develop softwares in any platform and to use any language. C# is a new language released with .NET.

Scope
This scope of this book provides basics of .NET platform. All the chapters in this book can be divided into three sections.

BSIT 61 Basics of .NET

Introduction

In first section you will study .NET concepts and its architecture. Chapter 1 and 2 belong to this section. The Chapter 1 is very important as it forms the clear foundation about the subject and it helps in understanding future chapters. Chapter 2 gives architectural details about .NET. In Second section, students will learn a new programming language C#. This language is used through out this book to understand the concepts of .NET via C# examples. Chapters 3, 4, 5 and 6 come in second section. Chapter 3 gives introduction about this language. Chapter 4 and 5 gives the C# language specifications. The 6th chapter includes some of the advanced topics of C#. The third section explores some of the important .NET technologies. The ADO.NET for database programming, internet technologies like web forms, web services, ASP.NET and the .NET remoting technique, all are covered in this section.

Significance of .NET
The Microsoft is well known for its operating system for home PC. From Windows 3.1 developed in 1992 to todays Windows XP, Microsoft has made many advances in its technologies. With the development towards new technology it has to maintain backward compatibility with the existing technologies. As the result of this huge number of new functions are added to the set of existing Windows APIs. (Windows API are set of basic functions provided by operating system. API functions can directly communicate with hardware). Backward compatibility is the strength of the Windows but at the same time backward compatibility has one major disadvantage. Every time the new technology is introduced, the new sets of features are added to Windows API. The existing technology is modified keeping backward compatibility in mind. This makes the code and the design much more complex. Again and again upgrading technologies makes the code so complex that after few years it becomes very hard to write new technology on existing one. To overcome these complexities there has to be one new fresh start. This fresh start is what .NET is all about. .NET is a new framework developed with new set of API. C# is a new language designed from scratch with .NET and for .NET platform. .NET platform supports object-oriented programming. The C# is a purely object-oriented language. The .NET framework has Visual Studio.Net which is the upgradation of Visual Studio. In Visual Studio Visual Basic (VB) was very well known for its simplicity and large number of controls but did not have good debugging feature. Whereas the VC++ had well built debugging feature, but did not had the simplicity and vast controls as in VB. Similarly there were many facts in which one technology was good in one and week at other. The Visual Studio.Net has overcome all these facts. Now VC++.Net has easily

BSIT 61 Basics of .NET

addable controls and VB.Net has good debugging features. The important thing to note is that even though the .NET is a fresh start it supports backward compatibility. It is capable of running applications developed in Visual Studio on Visual Studio.Net.

C#
C# (pronounced C Sharp) is a simple, modern, object oriented, and type-safe programming language. It is immediately familiar to C and C++ programmers. C# combines the high productivity of Rapid Application Development (RAD) languages and the raw power of C++. Here are some of the points about C#.
l

C# is a new language with .NET Framework. Its a purely object-oriented language and developed from scratch with .NET to make use of all feature of .NET. C# is a simple but powerful programming language intended for writing enterprise applications. The C# language is an evolution of C and C++. It uses many C++ features in the areas of statements, expressions, and operators. C# introduces considerable improvement and innovations in areas such as type safety, versioning, events, and garbage collection. C# provides access to the common API styles, COM, Automation, and C-style APIs. It also supports unsafe mode, where you can use pointers to manipulate memory that is not under the control of the garbage collector.

l l

System Requirements
To build and run your C# programs, you need
1 1 1 1

Windows 2000, XP, NT or Me IE 5.5 Microsoft .NET SDK (Beta 1) Visual Studio .NET (optional - available for MSDN Universal Subscribers)

4
1

Introduction

C# IDE Sharp Develop (optional).

The .NET SDK can be freely downloaded from http://msdn.microsoft.com/netframework Its an 80MB download. The C# compiler (csc.exe) currently ships with the .NET beta. The C# IDE is available from http://www.icsharpcode.net/OpenSource/SD/Download/Default.aspx

BSIT 61 Basics of .NET

Chapter 1

.NET Overview

By the end of this introductory section, you will know 8 8 8 Have a overview about .Net Framework Know what all Languages and Technologies are supported by .NET Advantages of .NET

Before we actually start with the subject, we have to make ourselves clear with the following questions.
1 1 1 1

Why should we study the Basics of .NET? What is the need of .NET? What is the pre-requisite for this subject? What should be the students role?

.NET is a new Framework from Microsoft. But what is this Framework? And what is inside it? .NET Framework comprises of programming methodologies (Visual Studio.NET and Mixed language programming), Platform technologies (ADO.NET, Windows Form) and Code Execution environment. All these things are comprised together into a framework, to provide object-oriented development platform. Let us take the above questions one by one. So why do we need to study this subject Basics of .NET? So far in your course you have studied programming languages like C, C++ and Java. If you compare all these languages you notice that the syntax of all languages is some what same. After you studied C programming, the efforts required to study C++ programming becomes less, isnt it? And when BSIT 61 Basics of .NET

Chapter 1 - .NET Overview

you started Java after C++, the Java language also looked easy to understand. But .NET is a Modern Software Technology. It is not just the programming language to learn, but a bunch of technology. It is time to learn the current generation software practice, using .NET. .NET has been built up with the aim to give provide modern software technology. This subject will help you to learn new programming methodologies and new technologies. The .NET framework has been built up so well that just knowing how its been designed is very interesting. Pre-requisite for this subject is knowledge about either C++ or Java, because the idea about the Object Oriented Programming (OOP) would make understanding of .NET concepts easy. Students should not have to be an expert in OOP, just the idea of it will do. As the .NET Framework is built on complete object oriented methodology, and it supports OOP, the knowledge of OOP is essential for the students. To explore the .NET and its features, we require a language. C# would be a best choice, because C# was designed on .NET Framework. C# has a capability to make best use of all .NET services. It resembles C++ and Java syntactically, so students who know anyone of these programming languages would learn fast. Any subject will be interesting only if the students are regularly exercised with it. In this book at the end of each chapter, there are set of questionnaires. The students must solve all these questionnaires, after studying each chapter. These questionnaires are designed to help students to analyze themselves and understand the chapter better.

1.1 .NET FRAMEWORK OVERVIEW


From the above discussion, you can broadly make out that the .NET Framework is an environment for the developers. It mainly comprised of programming methodology and technologies. To understand the .NET Framework, we should explore three major areas
l l l

Programming Methodologies Platform Technologies Code Execution

There is two ways of learning .NET. One is Breadth wise learning and the other is Depth wise learning. In Breadth wise learning, we will explore all the features and services of .NET. We will not analyze each area or services in depth; we just understand what is the role of each area. In Depth wise learning, we analyze each area, its role and its services. This type of learning is done by professional programmers, when they start programming in a particular area. Generally Depth wise learning comes after Breadth wise learning. This book provides only Breadth wise learning. This book tries to cover most important areas of .NET, so the students are exposed to the new world of software development.

BSIT 61 Basics of .NET

Programming Methodology
On the Programming Methodology side, an interesting thing about .NET is that it allows for mixedlanguage programming. By designing from the ground up a specification that is common to all the languages that work in .NET Framework, by designing a type system that all those languages support, and by specifically designing an intermediate language that all those languages compile into; before they compile in native code. The designers of .NET were able to build a system where the programmer can freely mix modules of the program between one language and another. For example, we might write our user interface in C#; we might write some low-level computational code in C++. We might write some other part in Visual Basic. It just does not really matter in a .NET framework. This technology is a publicly stated and internationally approved standard by the ECMA Group. C# is simply another programming language that now has a standard definition; it can be implemented by any manufacturer on any platform. It is the language that was designed specifically to be the best language to use with the .NET platform.

Platform Technologies
In Platform technologies, we will mainly go through ADO.NET, Internet technologies and User interface designing. The following paragraphs talks about these topics. Let us move to Platform Technologies, a little bit. In .NET framework we have put together platforms within the platform. ADO.NET is the technology that is used for accessing databases. .NET has improved that kind of programming dramatically from an ease-of-use standpoint, through some features. There is an entity called a strongly typed database. We will see how that works in later chapter, when we get to database programming. The net effect of ADO.NET for the programmer has greatly simplified and enhanced capability of programming with databases. It is a really nice technology. .NET also uses a disconnected model of database programming where we have a database sitting out on a database server. What we do is acquire the data from the database that we want into an end-memory dataset, and then we program against that. Moving into the Internet world, this was certainly one of the keystones of the development of .NET, as we can tell from the name. The particular part of the technology that deals with the Internet is called ASP.NET. There are two or three things that we have to talk about here. In the first place, there is something called Web Forms. The idea of developing software for the Internet can be tricky. It can be especially tricky if we are trying to have a reasonable amount of programming logic sitting behind a Web page. The Web Forms brings visual design to Web page, just like with an ordinary Windows program. We can write web designing code in any language that we want to. We are not limited to some scripting language. If we want to program our Web page in C#, we are allowed to do that. We can again mix the languages; we can do whatever we want. It is a very interesting new way of writing Web applications. The idea here is to look at the other side of the Internet. Certainly a lot of people believe that the part of the Internet that is going to ultimately prove to be the most valuable is not browsing the Web in the

Chapter 1 - .NET Overview

normal way that a user does, but computer-to-computer communication. That seems to be a great future for business-to-business type applications and a great many other server-software development activities are going to depend in the future on Web Services. There is a very strong support for web services in Microsoft .NET. Not only it is strong, it is simplified from the standpoint of the programmer. It is easy to write software that runs on one machine but is called by a program on another machine and sends its results back to other machine. Web services are one of the key components that we will talk about in later chapter. .NET Remoting is sort of Web services, its implementation lets us think about how one computer can interact with and access objects that are stored at another computer, without having to worry as a programmer about the low-level protocol details. It is a more powerful version of Web services. Another place where .NET has innovated is in User Interface Design. It has started with, in the world of Visual Basic. In C++ we struggle with hacking code to position our buttons and our text boxes, whereas the Visual Basic people were just dragging them on the screen and putting them where they wanted them. In .NET we can do that in any language. Thats the beauty of the common-language approach. It is the beauty of the tools that Microsoft has built, that works with those languages. The Windows programs that run under .NET which are designed visually are called as WinForms. There is another interesting concept called Data Binding. We often put fairly complicated controls on the surface of our application screen. For example, we want to put up a table that is a grid, which is supposed to display some data that comes into a dataset out of a SQL Server. So, how do we get it from our end memory (say SQL server) dataset into the user interface widget that is supposed to display it in some sort of list box or grid? .NET supports a concept called data binding that lets that happen completely automatically. The data source for this grid is this particular dataset, and that is the end of it. If we change the dataset, the grid updates automatically. If we change the grid programmatically, it updates into the dataset, and then we can decide whether to commit those changes to the database. It is a very nice and very powerful concept.

Code Execution
The interesting thing about code execution on .NET framework is, when we hear about .NET, we think, that it is particular to Intel-based computers. But it is certainly not. The standardized common language infrastructure is completely architecture-neutral. The whole purpose of making it standard and putting it in the public domain was so that that infrastructure could be implemented on any platform whatsoever. The whole idea is that we are neutral in terms of the architecture. Another interesting idea in .NET, of course, is the notion of just-in-time compiling. In the .NET platform, all the .NET languages get compiled into the Microsoft Intermediate Language or simply called as intermediate language. This intermediate language gets compiled by just in time compiler, to the native machine code. Just-in-time compiler has another great feature; it compiles the part of code as and when required. One of the nice features that all modern languages exhibit is garbage collection. With this garbage collector, programmer does not have to worry about freeing memory that has been allocated for some purpose. It is automatically done. Naturally, that is a great burden lifted off the programmers

BSIT 61 Basics of .NET

shoulders, as opposed to certain other languages, say in the C family of languages where we are constantly fighting that problem. Certainly, one of the goals was to have type safety. That is one of the hallmarks of C# and the other .NET languages. It is obviously the modern way to go about programming. The .NET is a technology that was designed for and really born out of the idea of how can we make it easier to write software? How can we make it easier to write software for Windows, how can we make it easier to write software that works through the Internet, how can we take some of the development time that people are spending on low-level details, and simply do them automatically? .NET answers all the above questions and lets the programmer get on with the real job. That is what .NET is about. It introduces the language C#. It is a language that has become very favorably inclined to developers nowadays. Certainly it is language of choice these days in any software that they are going to write. C# is the newest major language that is been designed. The people, who built software in all the other languages, now know what works; they know what is frustrating. They know what is powerful; they know what is not needed. The designers of .NET tried to make the best decisions that they thought they possibly could in putting together a new language that would be tailored to this framework but serve the needs of a programmer. They did an amazingly good job at it.

1.2 LANGUAGES AND TECHNOLOGIES


The .Net framework has integrated few main languages and other existing technologies within it. Let us have a brief look at them.

C#
C# is a new language developed with .NET and for .NET platform. It is a new language, which is capable of using all services provided by Dot Net platform. C# compiler always produces managed code after compilation. C# language is significant because of two important facts 1. It is highly compatible with the .Net Runtime. It is designed to run on .Net environment. 2. It is a modern object-oriented programming language. The word modern specifies some new techniques are used in designing this object-oriented language.

C++
Even with new and more powerful language C#, .Net also supports C++ because of backward compatibility. Many features are added to the C++ to make it stronger on .Net framework. To run a C++ code on .Net framework, we need to include below line at the beginning of the code. #using <mscorlib.dll>

10

Chapter 1 - .NET Overview

The compiled code will be managed code. But if the code is unsafe using low level pointer manipulation, then the C++ compiled code dose not pass CLR memory safety checks.

J++
No updations are made to this language. It is supported on .Net only for backward compatibility. There is much similarity between the J++ and C# syntax, So a tool which converts the J++ code to C# code is provided by .NET. Using this tool we can use convert J++ application to C# and use the facilities provided to C# language.

VB.NET
Visual Basic is been upgraded to Visual Basic.Net (VB.NET) on .Net Framework. Many new features and many new controls are added. Good debugging facility is provided. The compiled code of VB.NET is intermediate code as in the case of C#. The VB applications also work on VB.NET as the backward compatibility does exist.

ASP.NET
ASP is upgraded to ASP.NET on .Net Framework. The coding can be done directly in any of C#, VB.NET or JScript.NET. The code is compiled into classes which respond to the web requests. Because of backward compatibility the ASP code still continues to run on this new platform.

Scripting Languages
JScript is now upgraded to JScript.NET. The JScript.NET is used to code ASP.NET applications. As before now the Jscript is not interpreted, it is now compiled to intermediate code.

ADO/OLE DB
ADO.NET has been added new features like communicating with data sources which is made easy. ADO.NET is now the subset of .NET Base Classes.

COM and COM+


The COM+ remains as an important tool in .NET. COM works on .NET because of backward compatibility. Now on .NET Framework, calling and managing the components has become easy because .NET incorporates the COM interoperability feature.

1.3 ADVANTAGES OF .NET


The .NET Framework offers a number of advantages to developers. The following are few important among them.

BSIT 61 Basics of .NET

11

Consistent Programming Model


Different programming languages have different approaches for doing a task. For example, accessing data with a VB application and a VC++ application is totally different. A developer has to know both different techniques to do the task. In case of .NET Environment, for the same example, displaying data from database in a grid accessing data with a VB.NET and a C# is very similar except slight syntactical differences. Both the programs use the System.Data namespace, establish a connection with the database and run a query and displays the data on a data grid. The .NET there is a unified means of accomplishing the same task by using the .NET Class Library, a key component of the .NET Framework. The .NET Class Library provides the functionality to all .NET languages resulting in a consistent object model regardless of the programming language used by the developer.

Language Independence
Language Independence means the developer has the independence to code one module of an application in one language and other module of same application in other language. This language interoperability can help in code reuse and improve the efficiency of the development process.

No versioning Problem - Easy Application Deployment and Maintenance


The .NET Framework makes deployment of applications easy. Commonly, to install an application all we need to do is, copy the application along with the components it requires into a directory on the computer. The .NET handles the details of locating and loading the components an application needs, even if several versions of the same application exist on the computer. The .NET ensures that all the components the application depends on are available on the computer before the application begins to run.

Improved Security
The .NET Framework provides several mechanisms for protecting resources and code from unauthorized users:
l

ASP.NET Web Application Security provides a way to control access to a web site by comparing authenticated permissions with File System permissions for proper authorization. Code access security uses permissions to control the code accessing protected resources and operations. The computer systems are protected from suspicious mobile code and provide a way to run mobile code to safely. Role-based security provides information needed to make decisions about users permissions.

Support for Web Services


Web services are remote databases and programs, which access other computers to read the data

12

Chapter 1 - .NET Overview

files. With the advent of .NET technology, web services provide many built in Base Class library facilities which open up a whole new world of information for users. Web services can provide everything from basic text news information to vital database or application information

Dynamic Web
Content that changes with the user and user preferences is an example of dynamic web content. Dynamic web content is easier to create with .NET. ASP.NET and Visual Studio.NET allow developers to create dynamic web much easier than IIS and ASP technologies.

Visual Studio.NET
Visual Studio.NET is the Microsoft application and interface for programming in .NET. Visual Studio .NET provides all the programming advantages mentioned so far. This development environment has extensive set of ready to use controls, good debugging facilities, easy and simple programming features and vast set of .NET Base Classes.

SUMMARY
Microsoft has developed .NET Framework. .NET Framework is comprised of programming methodologies like Visual Studio.NET and Mixed language programming, Platform technologies like ADO.NET, Windows Form, etc and Code Execution environment. We have briefly explored .NET framework in this chapter. The .Net framework has integrated few main languages and other existing technologies within it. They are C, C++, J++, VB.NET, ASP.NET, Scripting Languages- JScript.NET, ADO.NET, COM and COM+. The advantages of .NET Framework are:
l l l l l l l

Provides Consistent Programming Model Has Language Independence No versioning Problem - Easy Application Deployment and Maintenance Improved Security Support for Web Services Dynamic Web facilities Full fledged Visual Studio.NET

QUESTIONS
1. What is .NET Framework?

BSIT 61 Basics of .NET

13

2. 3.

What does .NET Framework comprised off? Write a note on a. Programming Methodologies b. Platform Technologies c. Code Execution

4. 5. 6. 7.

Which are the Platform technologies supported by .NET framework? List out the advantages of .NET framework. What is backward compatibility? (Backward compatibility self study topic) Does .NET platform support backward compatibility? Explain.

14
Chapter 2

Chapter 2 - Components of .NET Framework

Components of .NET Framework

In this chapter, you will 8 8 8 8 Learn .NET Architecture and its Component Study each component like Common Language Runtime, Assemblies, Application Domains, Common Type System, and Metadata in detail Understand Common Language Specifications Briefly explore .NET Framework Class Library

2.1 .NET FRAMEWORK


In the previous chapter we had an overview about the .NET Framework. In this section we will see different layers of .NET framework. The below figure 1.1 will help us to understand the design of the framework better. Down in the bottom of the figure 1.1, we have operating system not only Windows on which .NET works on, there are also implementations that work under Linux. .NET Framework tries to provide an abstraction between application and operation system services. The .NET common language runtime knows how to get those services from the particular operating system. Common language runtime is running on top of operating systems. It is the execution engine in which a .NET programs execute. It also provides memory services and garbage collection.

14

Chapter 2 - Components of .NET Framework

BSIT 61 Basics of .NET

15

VB.NET

C++

C#

Scripting Languages

ASP.NET

Common Language Specification


Microsoft Visual Studio .NET

Framework Base Class Library

Common Language Runtime

Windows

LINUX
Figure 1.1 : Layers of .NET Framework

Sitting on top of common language runtime is a very large class library. That is the part of .NET which provides all those different platforms technologies that we were talking about in previous chapter. Like ADO.NET to access databases or ASP.NET to write Internet-enabled software. All those services reside in what we call collectively as Framework Base Class Library. Sitting on top of all, is ultimately some programming languages. As mentioned earlier that .NET supports language interoperability and to implement it, Microsoft has created a common language specification. These specifications are rules by which any .NET language has to play. If the application is implemented based on these rules then it can quite freely interoperate with any of the other .NET languages. Some of the major functions that the common language runtime provides are shown in below figure 1.2.
Common Language Runtime Execution Environment Memory Management Garbage Collection

Figure 1.2 : Common Language Runtime and its major functionalities

16

Chapter 2 - Components of .NET Framework

It is, as mentioned, the execution environment. It is the place where code executes. That means that the common language runtime is managing or denying memory access. It is the part of the Framework that does memory management. When new objects are created, they are created on the managed heap, and that is taken care of by the common language runtime. It garbage collects those objects which are no longer needed. Garbage collection is completely automatic. Another interesting part of all this, part of the common language runtime, is what we call the Common Type System. The reason it is interesting is the following; every object in a .NET program inherits from a common superclass called Object. As shown in the below figure 1.3. There are two main types; value types and reference types. This is a way that .NET languages differ a little bit from some other programming languages.

Figure 1.3 : Common Type System

Value types in .NET are what you normally think of as the primitive types in a programming language. ints, doubles, strings, all those sorts of things. Here ints, doubles and string all are objects and they have methods. It means the integer 2 (here 2 is a object) has a method called tostring, which you can call to get back the string version of the integer 2. Here it is a unified type system where value types, reference types, whatever they are, they are all objects. They all share a certain common level of behavior. Value types are allocated on the stack. So few questions to be cleared here are: Being a value type, what happens when you assign one to another? The value gets copied. How are they de-allocated? If theyre allocated on the stack, theyre obviously de-allocated when that block that is using that stack exits.

BSIT 61 Basics of .NET

17

Can we have user-defined types? Yes we can. We have the notion of structs in .NET languages and those are user-defined value types. Now a few word about the reference types. The reference types are objects. They are what we normally think about in object-oriented programming environments like classes and arrays. They are allocated on the managed heap, not on the stack. An reference type assignment, just copies the reference. If we have some type of object, says a customer, and we assign customer1 to customer2, we have not copied the entire object in all of its state. We have simply copied the reference. Reference types are garbage-collected. They are never explicitly freed. The common language runtime takes care of that. About Framework class library the main thing to say is, it is big. There is an amazing wealth of tools within it. They are divided into namespaces. System namespace is the highest level; it contains a few definitions and also contains some of the other namespaces.

Framework Class Library _____________________ System System.Collections System.Drawing System.IO System.Data System.Windows.Forms System.Web.UI System.Web.Services

Figure 1.4 : Framework Class Library and its major library classes

The Collections namespace contains the definition of collection types like stacks, queues, and hash tables, an array list. All the things you would expect in any modern programming language are in it. There is a drawing library that gives you access to a very rich set of tools for doing drawing and graphics I/O. The Data namespace contains the ADO.NET database tools. Windows.Forms is the part of the library that deals with writing the User Interface for Windows applications. Web.UI deals with that for Webbased applications and Web.services. The Framework class library is extensive and very large. Here we will see back at the big picture in figure 1.1 again. We have got operating systems. We have got a common language runtime looking over our code. Large framework base class library above common language runtime. On top of all, we have got program languages, and letting us get an access to all of it is Visual Studio .NET. Let us talk a little bit more about how languages work. A common language specification layer underneath

18

Chapter 2 - Components of .NET Framework

all languages, are in some sense bounded by the same rules. They are all using the same basic definitions for the primitive types. The way it works is shown here in below figure 1.5. This figure shows interesting part of the design of the .NET approach.

C# Code

C# Compiler

Visual Basic

Code

Visual Basic

Compiler

Intermediate Language

JIT Compiler

C++ Code

C++ Compiler

Native Code

Figure 1.5 : Common Language Specification support language interoperability through intermediate language

Naturally, if we are writing application in C#, we need a C# compiler. If we are writing in Visual Basic, we need a Visual Basic compiler. Even for C++, we need a C++ compiler. The approach taken here is that all of those compilers compile into this same intermediate language. The intermediate language is then compiled by Just-In-Time compiler to native machine code. So regardless of what language we write our code in, it all compiles into same intermediate language. That language is the same no matter what the source code was. Once we reach that stage, there is no way to even know or care what the original source code language was, it is all just compiled into the intermediate code. The designers of .NET had in their mind from the very beginning the idea that they were going to use a just-in-time compiler. The idea is, that just-in-time compiler only needs to understand one language, not all of them. It only needs to understand the intermediate language. It compiles it into native code and naturally, that does not take place until run time. Thats the .NET approach. We compile it into intermediate code. That is the result of the compilation process. It sits on the machine and when the user finally runs that code, it is compiled as needed into native code on the fly. Thats the just-in-time part. That process is obviously completely automatic and independent of how the program is coded. Once we have compiled it into intermediate language, its done. The common language runtime takes care of the rest. The reason for doing this, of course, is performance. No matter in which

BSIT 61 Basics of .NET

19

.NET language we are writing in, when it comes time to running the code, it is running as native compile code, and it runs very, very fast at many native-code speeds. That was the goal of this approach. .NET gives a managed execution environment. We get automatic memory management. We get garbage collection. We get lots and lots of libraries that allow us to write very rich programs in a very short amount of time. We also get a set of application programming interfaces that enable the writing of Internet-based software. That is just one of the cornerstones of .NET, and it is one of the things that make programming fun. Intermediate language gives a way to achieve language interoperability. Just think about it. If all the languages compile into the same intermediate language, then why shouldnt code from one be able to call up code from another? After all, once we are at that stage, there is no difference. That is exactly the way it works. We can write a class in C#. We can derive a subclass from it in Visual Basic. One of those objects might throw an exception. We can catch that exception in some other part of the code that is written in yet another language. It means we can tailor each part of a multi-module program in such a way that we use the language that is most appropriate for it. This is what the designers were shooting at. We also get from .NET Visual Studio, a rapid development environment that is absolutely perfect. Developers now do not need to keep fighting with the environment; they can just think about the code that they are writing. We also get a very interesting new language, C#. We will be moving into that topic C#, in next chapter. It is a cutting-edge, state-of-the-art language that exhibits all the best things that we currently know about designing a higher-level language.

2.2 .NET ARCHITECTURE AND ITS COMPONENT


The .NET Framework is a new computing platform that simplifies application development in the highly distributed environment of the Internet. This section gives technical description about .NET architecture. The Objectives of .NET Framework are:
l

To provide an object-oriented programming environment whether object code is stored and executed locally, or executed remotely. To provide a code-execution environment that minimizes software deployment and versioning conflicts. To provide a code-execution environment that guarantees safe execution of code, including code created by an unknown or semi-trusted third party. To provide a code-execution environment that eliminates the performance problems of scripted or interpreted environments.

20
l

Chapter 2 - Components of .NET Framework

To make the developer experience consistent across widely varying types of applications, such as Windows-based applications and Web-based applications. To build all communication on industry standards to ensure that code based on the .NET Framework can integrate with any other code.

The .Net Runtime sits between the Windows operating system and the application programs built on .Net technologies. The below figure demonstrates that the .Net application programs cannot directly communicate with the operating system. The .Net runtime uses the .NET base classes to communicate with operating system.
.NET Framework .NET Application Programs

.NET Runtime & Base Classes Windows Operating System Windows API

Figure 1.6 : .Net Runtime and Base class library lies between the application programs and operating system

We can classify the programming on Microsoft Windows platform into two types 1. Windows Programming 2. .NET Programming In Windows Programming the application programs call windows API function directly. The applications run in the windows environment i.e. operating system itself. These types of applications are called unmanaged or unsafe applications. In .NET Programming the application programs call .Net Base Class library functions which will communicate with operating system. The applications run in .Net Runtime environment. These types of applications are called as managed or safe applications. The .Net Runtime starts code execution, manages threads, provides services, manages memory etc. The detailed description is provided in next section. The .Net Base classes are fully object-oriented. It provides all functionalities of traditional windows API along with functionalities in new areas like accessing database, internet connections and web services. Some definitions of .Net components and other terminologies are given below. These terms or definitions have to be understood well before moving on to the detailed study about .NET.

BSIT 61 Basics of .NET

21

Common Language Runtime (CLR) This is also known as .NET Runtime. The code management is a fundamental principle of the runtime. The responsibility of runtime is to load the code, run the code and provide all kinds of services. The services provided by .NET Runtime are as memory management, thread management, remoting, strict type safety, ensure code security and robustness.

Managed Code Managed code is one which is designed to run on .Net environment. The code which runs in windows environment is unmanaged code.

Intermediate Language (IL) This is also called as Microsoft Intermediate Language (MSIL). The intermediate language is analogous to the byte code of Java. The significant difference is that the byte code in interpreted while the IL is compiled by JIT compilation to native machine code.

.NET Source Code

Compiler

Intermediate Language (IL)

IL Code

JIT Compiler

Native Machine Code

Figure 1.7 : .NET programming languages compilation process

The IL code is not the machine code. The .Net Runtime calls the Just-in-Time (JIT) compiler to get native machine code from IL code. This feature makes the .NET platform independent.
l

Common Type System (CTS) This is a standardized agreed set of basic data types. This system provides a way for language interoperability. Language Interoperability means that a object implemented in one language can call a object implemented in another language. In more general way you can say that a application can be developed in two or more languages supported by .Net framework. To make use of language interoperability feature, the developers have to follow CTS.

22
l

Chapter 2 - Components of .NET Framework

.NET Base Classes .NET Base Classes is a library comprising of extensive set of functions for all services supported by the framework. This vast collection has well written code for almost all tasks on all services of .Net framework. The services can be windows creation/displaying or form handling, internet or web services, database accessing or file handling.

Assemblies An Assembly is the unit in which compiled managed code is stored. An Assembly contains IL and metadata. Metadata gives details of the assembly, properties and methods stored in it, security information etc.

Common Language Specification (CLS) The set of rules of basic language features has been defined to enhance and ensure language interoperability is called the Common Language Specification (CLS). The CLS rules define a subset of the CTS.

Reflection The process of obtaining information about assemblies and the types defined within them as metadata at runtime.

Just-in-Time (JIT) Compilation The compilation converts IL into its native machine code. The name Just-in-Time is because it compiles portion of code as and when required at run time.

Manifest The area of assembly where metadata is stored is called as manifest.

Application Domain A boundary that the common language runtime establishes around objects created within the same application is by means of Application Domain. Application domain allows different code to run in the same process space.

Garbage Collection The Garbage Collector frees the application from the responsibility of freeing memory when no longer required. CLR calls Garbage collector to handle memory efficiently.

.NET is tiered and modular. Each tier of the .NET Framework is a layer of abstraction. .NET languages are the top tier and the most abstracted level. The Common Language Runtime (CLR) is the

BSIT 61 Basics of .NET

23

bottom tier, the least abstracted, and closest to the native environment. This is important since the CLR works closely with the operating environment to manage .NET applications. The .NET Framework is partitioned into modules, each with its own distinct responsibility. The higher tiers request services only from the lower tiers, so .NET is hierarchal. The modified architectural layout of the .NET Framework is illustrated in figure 1.8 below.

Figure 1.8 : Modified architectural layout of .NET Framework

The .NET Framework is a managed environment. The CLR monitors the execution of .NET applications and provides required services. It manages memory, handles exceptions, ensures security, and much more. Language interoperability is one goal of .NET. .NET languages share a Common Language Specification (CLS), Common Type System (CTS) and Framework Base Class Library (FCL). Web Services, ADO.NET,

24

Chapter 2 - Components of .NET Framework

Windows or console applications and Remoting execute on CLR. In .NET, the programming language like C#, VB.NET, or JScript.NET has similar experience except little differences. .NET abstracts lower-level services, while retaining most of their flexibility. Assemblies, Application domains and metadata are brought to CLR environment before they are executed. Once they are brought to the execution environment, CLR takes the responsibility of managing and executing it. More details are provided in the following topics. The important components of .NET Framework are:
l l l l l l l

Common Language Runtime Assemblies Application Domains Common Type System Metadata and Self-Describing Components Common Language Specifications .NET Framework Class Library

Each of the above components are described in detail in the following sections

2.3 COMMON LANGUAGE RUNTIME


The .NET Framework provides a run-time environment called the Common Language Runtime, which manages the execution of code and provides essential services. Lets go through the functionalities of CLR and how does it accomplishes it. To enable the runtime to provide services to managed code, language compilers must emit metadata that describes the types, members, and references in your code. Metadata is stored with the compiled code. Every loadable file contains metadata called as portable executable (PE). The runtime uses metadata to locate and load classes, lay out instances in memory, resolve method invocations, generate native code, enforce security, and set run-time context boundaries. The runtime automatically handles object layout and manages references to objects, releasing them when they are no longer being used. Automatic memory management eliminates memory leaks as well as some other common programming errors. The CLR makes it easy to design components and applications whose objects interact across languages. Objects written in different languages can communicate with each other, and their behaviors can be

BSIT 61 Basics of .NET

25

tightly integrated. This cross-language integration or language interoperability is possible because language compilers and tools that target the runtime use a CTS defined by the runtime, and they follow the runtimes rules for defining new types, as well as for creating, using, persisting, and binding to types. The runtime uses metadata information to ensure that your component or application has the specified versions of everything it needs, which makes your code less likely to break due to some dependency. Registration information and state data are no longer stored in the registry where they can be difficult to establish and maintain. Rather, information about the types and their dependencies is stored with the code as metadata. The managed execution process includes the following steps:
l l

Choosing an appropriate language compiler. Compiling code to Microsoft intermediate language (MSIL or simply IL). Compiling translates source code into IL and generates the required metadata. Compiling IL to native code. At execution time, a just-in-time (JIT) compiler translates the IL into native machine code. During this compilation, code must pass a verification process that examines the IL and metadata to find out whether the code can be determined to be type safe. Executing code. The CLR provides the environment that enables execution to take place as well as a variety of services that can be used during execution.

NOTE: In the above paragraphs some words are in italic. Those paragraphs are based on those word or concepts.

2.4 ASSEMBLIES
Assembly is a basic element of packaging in .NET. An assembly consists of IL code, metadata that describes what is in the assembly, and any other files or information that the application needs to run, such as graphics and sound files. An assembly performs the following functions:
l

It contains code that the CLR executes. Assembly contains IL code plus the manifest in a portable executable (PE) file will be executed by CLR. Note that each assembly can have only one entry point (i.e., DllMain, WinMain, or Main). An assembly is the unit at which permissions are requested and granted. Hence it forms a security boundary. It forms a type boundary. Every assembly has a unique name and the types within those assemblies includes the name of that assembly. Hence every type has unique name or unique boundary.

26
l

Chapter 2 - Components of .NET Framework

The assemblys manifest contains assembly metadata that is used by CLR for resolving types and satisfying resource requests. It forms a version boundary. The assembly is the smallest versionable unit in the CLR. All types and resources in the same assembly are versioned as a unit. The assemblys manifest describes the version. It forms a deployment unit. When an application starts, only the assemblies that the application initially calls must be present. Other assemblies, such as localization resources or assemblies containing utility classes, can be retrieved whenever they are called. This allows applications to be kept simple and thin at first.

Assemblies can be static or dynamic. Static assemblies can include .NET types (interfaces and classes), as well as required resources for the assembly (bitmaps, JPEG files, resource files, and so on). Static assemblies are stored on disk in PE files. Dynamic assemblies are one which run directly from memory and are not saved to disk before execution. They can be saved disk after they have executed.

2.5 APPLICATION DOMAINS


Application domains provide a secure and versatile unit of processing that the CLR can use to provide isolation between applications. This isolation is necessary to ensure that code running in one application cannot adversely affect other unrelated applications. Application domains are typically created by runtime hosts, which are responsible for bootstrapping the CLR before an application is run.

Physical Memory

Portion of physical memory or disk space

Process 1

Portion of physical memory or disk space

Process 2

Figure 1.9 : Separate process for each application in traditional execution environment

BSIT 61 Basics of .NET

27

Historically in traditional case, process boundaries have been used to isolate applications running on the same computer. Each application is loaded into a separate process, which isolates the one application from other applications running on the same computer. The applications are isolated to provide process security. As a result process cannot make direct call to another process. Instead, IPC techniques have to be used to have communication in between the processes. Each application is a separate process. In case of .NET Framework, Application domains provide a secure and versatile unit of processing that the CLR can use to provide isolation between applications. Several application domains can be run in a single process with the same level of isolation that would exist as separate processes, but without incurring the additional overhead of making IPC calls or switching between processes. A process is divided into number of application domain, where each application domain corresponds to separate application. But there is clear isolation between them with the advantage of easily sharing data.

PROCESS Application Domain : Application 1 uses some part of virtual memory :

Application Domain : Application 2 uses some part of virtual memory :

Figure 1.10 : Single process for multiple application domain in .NET execution environment

The ability to run multiple applications within a single process increases server scalability and overall efficiency.

2.6 COMMON TYPE SYSTEM


The Common Type System (CTS) defines how types are declared, used, and managed in the runtime. It is an important for Language Interoperability. The CTS performs the following functions:
l

Establishes a common framework that enables cross-language integration, type safety, and high performance code execution. Provides an object-oriented model.

28
l

Chapter 2 - Components of .NET Framework

Defines rules that languages must follow, so that different languages can interact with each other.

This section describes concepts and defines terms that will help you understand and work with language implementation of the CTS.

Classification of types
The CTS supports two categories: 1. Value types 2. Reference types The following diagram illustrates type classification described in above paragraphs.

Figure 1.11 : Type Classification

Value types directly stores data in the variable. Value types can be built-in type, user-defined types, or enumerations. Reference types store a reference to the datas memory address. Reference types can be selfdescribing types, pointer types, or interface types. Self-describing types are further split into arrays and class types. The class types are user-defined classes, boxed value types, and delegates. All types derive from the System.Object base type.

BSIT 61 Basics of .NET

29

2.7 METADATA AND SELF-DESCRIBING COMPONENTS


In the past, a software component (.exe or .dll) written in one language could not use or communicate with software component written in another language. The solution came in the form of COM components. The .NET Framework makes language interoperation even easier by allowing compilers to put additional information into all compiled modules and assemblies. This information, called Metadata. Metadata is binary information describing the program. When we compile our code into a PE file, metadata is inserted into one portion of the PE file, while the code is converted to IL and inserted into another portion of the PE file. Every type, member which are defined or referenced in a module is described within metadata. When code is executed, the runtime loads metadata into memory and refers it to get information about the codes classes, members, inheritance, and so on. Metadata stores the information like:
l l l l l l l l

Description of the assemblys operation. Assembly Identity (name, version, culture, public key). Exported types Other dependent assemblies Security permissions Description of types Members like methods, fields, properties, events, nested types, etc. Attributes

Benefits of Metadata
Metadata allows .NET languages to describe themselves in a language-neutral manner. It gives required information to CLR to perform much of its functionalities. The presence of metadata makes the assembly Self-describing file. The CLR modules or components or other assemblies which want to communicate with each other uses these information stored in metadata to perform their tasks.

2.8 COMMON LANGUAGE SPECIFICATIONS


What is the Common Language Specification? To fully interact with other objects regardless of the language they were implemented in, objects must follow some implementation rules. For this reason, a set of language features has been defined, called the

30

Chapter 2 - Components of .NET Framework

Common Language Specification (CLS). The CLS rules define a subset of the CTS i.e., all the rules that apply to the CTS apply to the CLS. The CLS helps enhance and ensure language interoperability by defining a set of features to the developers. Most of the members defined in the .NET Framework base class library are CLS-compliant. However, some types in the class library have one or more members that are not CLS-compliant. These members enable support for language features that are not in the CLS and to support backward compatibility. The CLS is large enough to include the language constructs that are commonly needed by developers, yet small enough that most languages are able to support it. The details for the CLS compliant features are given in MSDN .NET framework developers guide. These details are out of the scope of this course material.

2.9 .NET FRAMEWORK CLASS LIBRARY


The .NET Framework Base Class Library is a set of managed classes that provide access to system services. File handling, sockets, database access, remoting, and XML are some of the services available in the Base Class Library. All the .NET languages rely on the same managed classes of Base Class Library for the same services. It can be told that if you have learned any one .NET language, then working with other .NET languages will be easy. The same classes, methods, parameters, and types are used for all the system services regardless of any .NET language. Let us look at the following code that writes to and then reads from a file.
//Here is the C# version of the program. using System; using System.IO; static public void Main() { StreamWriter sw1=new StreamWriter("temp.txt", true); string tempstring="Hi, this is Gopal"; sw1.WriteLine(tempstring); sw1.Close(); StreamReader sr1=new StreamReader("temp.txt"); string filestring=sr1.ReadToEnd(); sr1.Close(); Console.WriteLine(filestring); } Here is the VB.NET version of the program. shared public sub Main() dim sw1 as StreamWriter=new StreamWriter("temp.txt", true)

BSIT 61 Basics of .NET

31

dim tempstring as string= "Hi, this is Gopal" sw1.WriteLine(tempstring) sw.Close() dim sr1 as StreamReader=new StreamReader("temp.txt") dim filestring as string=sr1.ReadToEnd() sr1.Close() Console.WriteLine(filestring) end sub

If we see both versions of the above program are nearly identical. The syntax and use of StreamReader, StreamWriter, and the Console class are identical: same methods, and identical parameters. .NET Base Class Library includes some 600 managed classes. Microsoft have partitioned the managed classes of Base Class Library into separate namespaces based on functionality. For example, local input/ output can be found in the namespace System.IO. Base Class Library namespaces are often nested. the levels of namespaces are delimited with dots. System.Runtime.InteropServices, System.Security. Permissions, and System.Windows.Forms are examples of nested namespaces. System is root namespace and provides classes for all system services.

SUMMARY
.NET Framework is layered architecture. Each layer provides abstraction to the layer above it. CLR provides a run-time environment, which manages the execution of code and provides essential services like Automatic memory management, language interoperability, security etc. Assembly is a basic element of packaging in .NET. An assembly consists of IL code and metadata that the application needs to run. Application domains provide a secure and versatile unit of processing that the CLR can use to provide isolation between applications. The CTS defines how types are declared, used, and managed in the runtime. It is an important for Language Interoperability. Metadata is binary information describing the program, which are stored in assemblies. CLS is a set of language features has been defined in order to support language interoperability. The CLS rules define a subset of the CTS. The .NET Framework Base Class Library is a set of managed classes that provide access to system services.

QUESTIONS
1. 2. 3. 4. With a neat diagram, explain the .NET Framework architecture. List out the objectives of .NET framework. How the Windows Programming is different from .NET Programming? Define the following a. CLR

32
b. c. d. e. f. g. h. i. j. k. l. 5. 6. 7. 8. 9. Managed Code Intermediate Language CTS .NET Base Classes Assemblies CLS Reflection JIT Compilation Manifest Application Domain Garbage Collection

Chapter 2 - Components of .NET Framework

What are functionalities of CLR? Give the steps involved in managed execution process. What are assemblies? What are static and dynamic assemblies? How the .NET execution environment with application domain differs from traditional way of execution? What is the function of CTS? Explain the classification of types in CTS with a diagram. Write a note on metadata.

10. It is told that if we learn any one .NET language, then working with other .NET languages will be easy. How? Explain with the appropriate example.

BSIT 61 Basics of .NET

33

Chapter 3

C# Language Tour

By the end of this chapter, you will 8 8 8 8 8 Have quick survey of C# features Know why to use C# See the first C# program Know the general structure of a C# program Be able to list out difference between C++ and C#

3.1 NEW PROGRAMMING LANGUAGE - C#


C# is new programming language designed for building enterprise applications that run on the .NET Framework. It is written as C#, but pronounced as C Sharp. C# is an evolution of C and C++. Many C++ language features and syntax statements, expressions, and operators are used by C#. It is a pure object oriented language. Compilation of C# code produces managed code, which has the benefits from the services of the common language runtime, such as language interoperability, enhanced security, and garbage collection. C# has many advanced improvement in type safety, versioning, events, and garbage collection.

BSIT 61 Basics of .NET

33

34 3.2 WHY C#

Chapter 3 - C# Language Tour

C# is a new language form Microsoft which is completely object-oriented. It has been developed from scratch on .NET framework with the intension to make use of all service of .NET framework in efficient manner. Important features of C# language design are:
l l

C# is an elegant, simple, type-safe, object-oriented language. C# has the capability to build durable system-level components due to following features:
l l l l

Full COM/Platform support for existing code integration. Robustness through garbage collection and type safety. Security provided through good design. Full support of extensible metadata concepts.

C# supports Language Interoperability and Platform Independence due to following features:


l

Full interoperability with COM and .NET Framework services, through tight .NET Library Base classes. XML support for web-based component interaction. Versionability.

l l

3.3 THE C# VERSION OF HELLO WORLD!


As in any other languages, we will also start our first C# program with a simple Hello World! string display program.
// A Simple "Hello World!" string display program in C# class Hello { static void Main() { System.Console.WriteLine("Hello World!"); } }

The important points to be noted in this program are:


l l

Comments The Main Method

BSIT 61 Basics of .NET

35

l l

Input and Output Compilation and Execution

Comments
Comments are used for proper documentation of the code. The compiler does not consider the comments as the part of code. Compiler ignores the comments during the time of compilation. Comments make the program more understandable. C# adopts the C++ style of comments. The first line is a comment:
// A Hello World! program in C#

The characters // convert the rest of the line to a comment. You can also comment a block of text by placing it between the characters /* and */, for example:
/* A Hello World! program in C#. This program displays the string Hello World! on the screen. */

The Main Method


The C# program must contain a Main method, in which control starts and ends. You can create objects and execute other methods within this Main method. Note that the alphabet M in Main is uppercase, where as in C and C++ it is lowercase. The Main method is a static method and resides inside a class. In the Hello World! example, it resides inside the Hello class. There are three ways y to declare the Main method:

Return type void:


static void Main() { ... }

Return type int:


static int Main() { ... return 0; }

Passing arguments
static int Main(string[] args) { ... return 0; }

The parameter of the Main method is a array of string which is command-line arguments.

36
Input and Output

Chapter 3 - C# Language Tour

In the above Hello World program there is only one output statement, no input statements. The statement:
System.Console.WriteLine(Hello World!);

uses the WriteLine method, of the Console class which resides in the .NET run-time library. This method displays its string parameter on the standard output followed by a new line. There are many other Console methods are used for different input and output operations. If you include the following using statement at the beginning of the program:
using System;

you can directly use the System classes and methods as show below. For example:
Console.WriteLine(Hello World!);

Compilation and Execution


The compile and execution commands given here are for command line compiler. We are not going into the Visual C# IDE. Follow the below steps to compile and execute a program.
l

By using any text editor create a source file and save it as Hello.cs. The C# source code files should have .cs extension. To compile the program use the command given below. If there are no compilation errors Hello.exe is created csc Hello.cs

To run the program, enter the command Hello

3.4 GENERAL STRUCTURE OF A C# PROGRAM


C# program can consist of one or more files. Each file can contain one or more namespaces. A namespace contains group of related types such as classes, structs, interfaces, enumerations, and delegates. Namespaces may be nested. The following is the skeleton of a C# program that contains all of these elements.

BSIT 61 Basics of .NET

37

// A skeleton of a C# program using System; namespace Namespace1 { class Class1 { } struct Struct1 { } interface Interface1 { } delegate int Delegate1(); enum Enum1 { } namespace Namespace2 { } class Class2 { public static void Main(string[] args) { } } }

3.5 USING FULLY QUALIFIED NAMES


Fully Qualified Names describe the logical hierarchy of the type or object. Namespaces and types always have unique names. For example, If there are 2 class with same name but are present in different namespaces then both the objects will have their unique fully qualified names.
namespace ABC { class Class1 { } } // ABC // ABC.Class1

38
namespace XYZ // XYZ { class Class1 // XYZ.Class1 { } }

Chapter 3 - C# Language Tour

Here the ABC.Class1 and XYZ.Class1 are two different types, even if the class name is same. In the following code example shows the nested classes and namespaces. Carefully examine the fully qualified names given as comments.
namespace ABC // { class Class1 { class Class2 { } } namespace XYZ // { class Class2 { } } } ABC // ABC.Class1 // ABC.Class1.Class2

ABC.XYZ // ABC.XYZ.Class2

From the above code example:


l l l l

The namespace ABC is a member of the global namespace. Its fully qualified name is ABC. The namespace XYZ is a member of ABC. Its fully qualified name is ABC.XYZ. The class Class1 is a member of the ABC. Its fully qualified name is ABC.Class1. The class name Class2 is used twice in this code. However, the fully qualified names are unique. The first one is declared inside Class1; thus its fully qualified name is: ABC.Class1.Class2. The second is declared inside a namespace XYZ; thus, its fully qualified name is ABC.XYZ.Class2.

Using the preceding code segment, you can add a new class member Class3 to the namespace ABC.XYZ as follows:
namespace ABC.XYZ { class Class3 // ABC.XYZ.Class3 { } }

BSIT 61 Basics of .NET

39

3.6 COMPARISON BETWEEN C++ AND C#


C# has the flavor of C++. C# resembles C++ in its syntax but has many important differences. A overview on most important differences between two languages are given below:
n n

C# is purely object-oriented language, whereas C++ support object-oriented programming. Arrays: The syntax of declaring C# arrays is different from that of C++ arrays. The tokens [] appear following the array type in C#. The bool type in C#: There is no conversion between the bool type and int. The long type: In C#, the long data type is 64 bits, while in C++, it is 32 bits. The struct type: In C#, classes and structs are semantically different. A struct is a value type, while a class is a reference type. The switch statement: Unlike the C++ switch statement, C# does not support fall through from one case label to another. The delegate type: Delegates are roughly similar to function pointers in C++, but they are typesafe and secure. Preprocessor directives are used for conditional compilation. No header files are used in C#. C# operators: C# supports additional operators such as is and typeof. It also introduces different functionality of some logical operators. The Main method is declared differently from the main function in C++. The usage of the command-line arguments is also different. Method parameters: C# supports ref and out parameters, which are used instead of pointers in passing parameters by reference. Pointers are allowed in C# but only in unsafe mode. Overloading operators is performed differently in C#. Strings: C# strings are different from C++ strings. The foreach keyword allows you to iterate through arrays and collections. No global methods or variables in C#: Methods and variables must be contained within a type declaration (such as class or struct). No header files or #include directives in C#: The using directive is used to reference types in other namespaces without fully qualifying the type names.

n n n

n n

n n n n n

40
n

Chapter 3 - C# Language Tour

Destructors: In C#, you dont have control over when a destructor is called because destructors are called automatically by the garbage collector. Constructors: Unlike C++, if you dont provide a class constructor in C#, a default constructor is automatically generated for you. The default constructor initializes all the fields to their default values. C# does not support bit fields.

SUMMARY
C# is new programming language, which is purely object oriented and designed for building enterprise applications that run on the .NET Framework. It is written as C#, but pronounced as C Sharp. C# program has the general structure as - it consist of one or more files. Each file can contain one or more namespaces. A namespace contains group of related types such as classes, structs, interfaces, enumerations, and delegates. Namespaces and types always have unique fully qualified names. C# has the flavor of C++ but is much more modern object oriented language.

QUESTIONS
1. 2. 3. 4. 5. List out the important features of C#. Write a program in C# to display Welcome to the world of C Sharp. Explain the program. Explain the general structure of a C# program. How do namespaces and types in C# have unique names? Give an example. List out the difference between C# and C++.

BSIT 61 Basics of .NET

41

Chapter 4

C# Language Specifications

In this chapter, you will 8 8 8 8 8 Study types and variables of C# language Automatic memory management concept with example Expressions and statements in C# Study C# features like structs, interfaces, delegates and enums Know what are namespaces and attributes

4.1 TYPES
In C# language the types are divided into two categories: 1. Value types 2. Reference types A third category pointers, is available only in unsafe code. Variables of the value types directly contain their data, whereas variables of the reference types store address of their data. With reference types, it is possible for two variables to reference the same object. With value types, the variables have their own copy of the data.

BSIT 61 Basics of .NET

41

42

Chapter 4 - C# Language Specifications

C# provides a set of predefined types which are identified through reserved words. The below table gives predefined types, description and examples.
Type Sbyte Short Int Long Byte Ushort Uint Ulong Float Double Bool Char decimal Description 8-bit signed integral type 16-bit signed integral type 32-bit signed integral type 64-bit signed integral type 8-bit unsigned integral type 16-bit unsigned integral type 32-bit unsigned integral type 64-bit unsigned integral type Single-precision floating point type Double-precision floating point type Boolean type; a bool value is either true or false Character type is a Unicode character Precise decimal type with 28 significant digits Examples Sbyte val = 12; Short val = 12; int val = 12; long val1 = 12; long val2 = 34L; byte val1 = 12; byte val2 = 34U; Ushort val1 = 12; ushort val2 = 34U; uint val1 = 12; uint val2 = 34U; ulong val1 = 12; ulong val2 = 34U; ulong val3 = 56L; ulong val4 = 78UL; float value = 1.23F; Double val1 = 1.23 double val2 = 4.56D; bool value = true; char value = 'h'; Decimal value = 1.23M;

Table 4.1 : Lists of predefined types in C#

A variable of a type always stores a data value of that type. But in case of reference types, it is possible for a data to be null or to reference an object of other derived type. Assignment to a value type variable creates a copy of the value being assigned. Whereas the assignment to a reference type variable, copies the address of object. A reference type is a class type, an string type, an interface type, an array type, or a delegate type. Boxing and Unboxing is a central concept in a C# type system. It provides a bridge between valuetypes and reference-types by allowing any data of a value-type to be converted to object and from object to data of value type. Boxing and Unboxing gives the way wherein, a value of any type can ultimately be treated as an object.

BSIT 61 Basics of .NET

43

4.2 VARIABLES AND PARAMETERS


Variables represent storage locations. Every variable has a type that determines what kind of data can be stored in the variable. C# is a type-safe language, the C# compiler guarantees that values stored in variables are always of the correct type. Variables can be initially assigned or initially not assigned. C# variable declaration have following syntax [optional_modifier] datatype identifier; Where optional_modifier is accessibility form There are seven categories of variables:
l l l l l l l

Static variables Instance variables Array elements Value parameters Reference parameters Output parameters Local variables

Let us see each of these categories in detail.

Static variables
A variable declared with the static modifier is called a static variable. There will be only one copy of the variable, regardless of how many instances of class (class in which static variable exists) are created.

Instance variables
A variables declared without the static modifier is are instance variables.

Array elements
The array is a container that has a list of storage locations for a specified type. The elements for a specified type of an array come into existence when an array instance is created, and exist until there are no references to that array instance.

Value parameters
Parameters are arguments passed to the function. A parameter declared without a ref or out modifier

44

Chapter 4 - C# Language Specifications

is a value parameter. A value parameter comes into existence when the function is invoked and is initialized with the value of the argument passed. A value parameter exists until the function returns.

Reference parameters
A parameter declared with a ref modifier is a reference parameter. A reference parameter does not create a new instance, it points to the same storage location of the parameter passed as an argument. Thus, a variable must be definitely initialized before it is passed as a reference parameter to a function.

Output parameters
A parameter declared with an out modifier is an output parameter. A reference parameter does not create a new instance, it points to the same storage location of the parameter passed as an argument. Thus, a variable need not be initialized before it is passed as a reference parameter to a function. But output parameter must be definitely assigned before the function returns.

Local variables
A local variable is declared and exits within a block, a for-statement, a switch-statement, or usingstatement. A local variable is not automatically initialized and thus has no default value.

4.3 AUTOMATIC MEMORY MANAGEMENT


Manual memory management requires developers to manage the allocation and de-allocation of blocks of memory. Manual memory management can be both time-consuming and difficult. In C#, automatic memory management is provided so that developers are freed from this burdensome task. Automatic memory management increases code quality and enhances developer productivity without negative impact on either expressiveness or performance. The example
using System; public class Stack { private Node first = null; public bool Empty { get { return (first == null); } } public object Pop() { if (first == null)

BSIT 61 Basics of .NET

45

Console.Write("Can't Pop from an empty Stack."); else { object temp = first.Value; first = first.Next; return temp; } } public void Push(object o) { first = new Node(o, first); } class Node { public Node Next; public object Value; public Node(object value): this(value, null) {} public Node(object value, Node next) { Next = next; Value = value; } } }

shows a Stack class implemented as a linked list of Node instances. Node instances are created in the Push method and are garbage collected when no longer needed. A Node instance becomes eligible for garbage collection when it is no longer possible for any code to access it. For instance, when an item is removed from the Stack, the associated Node instance becomes eligible for garbage collection. The example
class Test { static void Main() { Stack s = new Stack(); for (int i = 0; i < 10; i++) s.Push(i); s = null; } }

shows code that uses the Stack class. A Stack is created and initialized with 10 elements, and then in next statement it is assigned the value null. Once the variable s is assigned null, the Stack and the associated 10 Node instances become eligible for garbage collection. The garbage collector is permitted to clean up immediately. The garbage collector keeps moving around the objects in memory, but this motion is invisible to most C# developers.

46

Chapter 4 - C# Language Specifications

C# provides the ability to write unsafe code. Such code can deal directly with pointer types and object addresses, however, C# requires the programmer to fix objects to temporarily prevent the garbage collector from moving them. This unsafe code feature is in fact a safe feature from the perspective of both developers and users. Unsafe code must be clearly marked in the code with the modifier unsafe, so developers can not possibly use unsafe language features accidentally, and the compiler and the execution engine work together to ensure that unsafe code cannot masquerade as safe code. These restrictions limit the use of unsafe code to situations in which the code is trusted. The example
using System; class Test { static void WriteLocations(byte[] arr) { unsafe { fixed (byte* pArray = arr) { byte* pele = pArray; for (int i = 0; i < arr.Length; i++) { byte value = *pele; Console.WriteLine("arr[{0}] at 0x{1:X} is {2}", i, (uint)pele, value); pele++; } } } } static void Main() { byte[] arr = new byte[] {1, 2, 3, 4, 5}; WriteLocations(arr); }

shows an unsafe block in a method named WriteLocations that fixes an array instance and uses pointer manipulation to iterate over the elements. The index, value, and location of each array element are written to the console. One possible example of output is:
arr[0] arr[1] arr[2] arr[3] arr[4] at at at at at 0x8E0360 0x8E0361 0x8E0362 0x8E0363 0x8E0364 is is is is is 1 2 3 4 5

but, of course, the exact memory locations may be different in different executions of the application.

BSIT 61 Basics of .NET

47

4.4 EXPRESSIONS AND OPERATORS


An expression is a sequence of operators and operands that specifies computation and assigns the result to a variable. This section defines the syntax, order of evaluation of operators, and meaning of expressions. Expressions are constructed from operands and operators. The operators of an expression indicate which operations to perform. Examples for operators are +, -, *, /, etc. Examples for operands are literals, variables, and expressions. There are three kinds of operators: 1. Unary operators: The unary operators operate on only one operand. For example: x, x++, etc. 2. Binary operators: The binary operators operate on two operands. For example: x + y. 3. Ternary operator: There is only one ternary operator, ?:. The ternary operator operates on three operands. For example: condition? true_exp: false_exp The order of evaluation of operators in an expression is determined by the precedence and associativity of the operators. When an expression contains multiple operators, the precedence of the operators control the order in which the individual operators are evaluated. For example, the expression x + y * z is evaluated as x + (y * z) because the * operator has higher precedence than the + operator. The following table summarizes operators order of precedence from highest to lowest:

Category Primary

Operators x.y f(x) a[x] x++ x-- new typeof checked unchecked Unary + - ! ~ ++x --x (T)x Multiplicative * / % Additive + Shift << >> Relational and testing < > <= >= is as Equality == != Logical AND & Logical XOR ^

48
Logical OR Conditional AND Conditional OR Conditional Assignment

Chapter 4 - C# Language Specifications

| && || ?: = *= /= %= += -= <<= >>= &= ^= |=


Table 4.2 : Operator Precedence Table

When an operand occurs between two operators with the same precedence, the associatively of the operators controls the order in which, the operation is performed. Precedence and associativity can be controlled using parentheses. For example, a + b * c first multiplies b by c and then adds the result to a, but (a + b) * c first adds a and b and then multiplies the result by c. The assignment operators and the conditional operator (?:) are right-associative, i.e., operations are performed from right to left. For example, a = b= c is evaluated as a = (b = c).

4.5 STATEMENTS
C# provides a variety of statements. Most of these statements are similar to that of C and C++.

4.5.1 Blocks
A block permits multiple statements to be written as group. A block consists of list of single statements enclosed in braces.
{ // Begin a block Bool flag; flag = true; CallFunction(flag); // End a block

If the statement list within braces is omitted, the block is said to be empty.

4.5.2 The empty statement


An empty statement (;) is used when there are no operations to perform, but require an statement. Execution of an empty statement simply transfers control to the end point of the statement. An empty statement can be used when writing a while statement with a null body:

BSIT 61 Basics of .NET

49

while (WaitForAnEvent()) ;

An empty statement can also be used to declare a label just before the closing } of a block:
void Func() { ... if (true) goto exit; ... exit: ; }

4.5.3 Labeled statements


A labeled statement is prefixed by a label. Labeled statements are permitted in blocks. A label is a name given by the identifier. The scope of a label is the block in which the label is declared. If two labels have same name we get compile time error. A label can be referenced from goto statements within the scope of the label. Labels and other identifiers can have same name . The example
int Func(int abc) { if (abc >= 0) goto abc; abc = -abc; abc: return abc; }

is valid and uses the name abc as both a parameter and a label.

4.5.4 Selection statements


Selection statements select one of a number of possible statements for execution based on the result of an expression. In this section we will see few selection statements:

The if statement
The if statement executes the if block of a boolean expression result is true.

50
if (Boolean_expression) { // if block statements }

Chapter 4 - C# Language Specifications

An else part is can also be associated with the above if statement. The else block will be executed when the boolean expression result is false.
if (Boolean_expression) { // if block is executed if Boolean_expression is true } else { // else block is executed if Boolean_expression is false }

The switch statement


A switch statement executes the statements that are associated with the value of a given expression, or default of statements if no match exists. The example demonstrates the switch usage how this statement switches on the number of arguments provided.
class TestSwitch { static void Main(string[] args) { switch (args.Length) { case 0: Console.WriteLine(No arguments were provided); break; case 1: Console.WriteLine(One arguments was provided); break; default: Console.WriteLine({0} arguments were provided, args.Length); break; } } }

The switch expression must be an integer type, char or a string. The case labels have to be constants. The end of a case statement must explicitly state where to go next. The break statement takes the control to go out of switch statement.

BSIT 61 Basics of .NET

51

using System; class SwitchSelect { public static void Main() { string myInput; int myInt; begin: Console.Write(Please enter a number between 1 and 3: ); myInput = Console.ReadLine(); myInt = Int32.Parse(myInput); // switch with integer type switch (myInt) { case 1: Console.WriteLine(Your break; case 2: Console.WriteLine(Your break; case 3: Console.WriteLine(Your break; default: Console.WriteLine(Your myInt); }

number is {0}., myInt);

number is {0}., myInt);

number is {0}., myInt);

number {0} is not between 1 and 3.,

decide: Console.Write(Type \continue\ to go on or \quit\ to stop: ); myInput = Console.ReadLine(); // switch with string type switch (myInput) { case continue: goto begin; case quit: Console.WriteLine(Bye.); break; default: Console.WriteLine(Your input {0} is incorrect., myInput); goto decide; } } }

52 4.5.5 Iteration statements

Chapter 4 - C# Language Specifications

Iteration statements repeatedly execute a block of statements. The number of iterations depends on the condition represented by boolean expression. The block of code will be iterated until the condition is true. There are four iteration statement in C#: 1) while statement 2) do statement 3) for statement 4) foreach statement

The while statement


A while statement conditionally executes a statement zero or more times, as long as a boolean expression is true. For example, the program given below uses a while statement to find the position of first occurrence of a value in an array.
using System; class TestWhile { static int Find(int value, int[] arr) { int i = 0; while (arr[i] != value) { if (++i > arr.Length) return arr.Length; } return i; } static void Main() { Console.WriteLine(Find(3, new int[] {5, 4, 3, 2, 1})); } }

The do statement
A do statement conditionally executes a statement one or more times. The block is executed atleast

BSIT 61 Basics of .NET

53

once, and continues to execute until the condition or boolean expression in true. The below program demonstrates the usage of do statement. This program reads from the console until the Exit string is entered.
using System; class Test { static void Main() { string s; do { s = Console.ReadLine(); } while (s != Exit); } }

The for statement


A for statement evaluates a sequence of initialization expressions and repeatedly executes the block of statements until a condition is true. The below example uses a for statement to write out the integer values 1 through 10.
using System; class Test { static void Main() { for (int i = 0; i < 10; i++) Console.WriteLine(i); } }

The foreach statement


A foreach statement lets us iterate over the elements in arrays and collections. The elements of singledimensional arrays are traversed in increasing order of index, starting with index 0 to Length 1. The elements of multi-dimensional arrays elements are traversed such that the indices of the rightmost dimension are incremented first, then the next left dimension, and so on to the left. The below example uses a foreach statement to iterate over the elements of an array.

54
using System;

Chapter 4 - C# Language Specifications

class TestForeach { static void Main() { int[] array1 = new int[] {1,2,3,4,5}; foreach (int i in array1) Console.WriteLine(Value is {0}, i); } }

Jump statements
Jump statements unconditionally transfer control. Different jump statements supported by C# are:
l l l l l

break statement continue statement goto statement return statement throw statement

The above given jump statements perform same function as in any other languages like C, C++ or Java. The below table lists the kinds of jump statements and provides an example for each.

break statements

continue statements

static void Main(string[] args) { int i = 0; while (true) { if (i == args.Length) break; Console.WriteLine(args[i++]); } } static void Main(string[] args) { int i = 0; while (true) { Console.WriteLine(args[i++]); if (i < args.Length) continue; break; } }

BSIT 61 Basics of .NET

55
static int add(int a, int b) { return a + b; } static void Main() { Console.WriteLine(add(1, 2)); return; } static int F(int a, int b) { if (b == 0) throw new Exception("Divide by zero"); return a / b; } static void Main() { try { Console.WriteLine(F(5, 0)); } catch(Exception e) { Console.WriteLine("Error"); } }

return statements

throw statements and try statements

Table 4.3 : List of jump statements and their description

The break statement exits the nearest enclosing switch, while, do, for, or foreach statement. The continue statement starts a new iteration of the nearest enclosing while, do, for, or foreach statement. The goto statement transfers control to a statement that is marked by a label. The return statement returns control to the caller function. The throw statement throws an exception.

checked and unchecked statements


The checked and unchecked statements are used to control the overflow checking for integer type arithmetic operations and conversions. The checked statement causes all expressions in the checked block to be evaluated in a checked context, and the unchecked statement causes all expressions in the unchecked block to be evaluated in an unchecked context. The example for these statements
static void Main() { int x = Int32.MaxValue; Console.WriteLine(x + 1); // Overflow checked { Console.WriteLine(x + 1); // Exception } unchecked { Console.WriteLine(x + 1); // Overflow } }

56
lock statements

Chapter 4 - C# Language Specifications

The lock statement obtains the mutual exclusion lock for a given object, executes statements, and then releases the lock. The example is shown below
static void Main() { A a = ...; lock(a) { a.P = a.P + 1; } }

using statements
The using statement obtains one or more resources, executes statements, and then releases of the resource.
static void Main() { using (Resource r = new Resource()) { r.Func(); }

4.6 STRUCTS
Structs are similar to classes, they represent data structures that can contain data members and also function members. The difference is structs are value types and classes are reference type. A variable of a struct type directly contains the data of the struct, whereas a variable of a class type contains a reference to the object. Structs are useful for small data structures. The primitive types provided by C#, such as int, double, and bool, are in fact all struct types. Let us see an example, that use of a struct rather than a class for a Point can make a large difference in the number of allocations. The program below creates and initializes an array of 100 points. With Point implemented as a class, the program creates 101 separate objects, one for the array and one each for the 100 elements.

BSIT 61 Basics of .NET

57

class Point { public int x, y; public Point() { x = 0; y = 0; } public Point(int x, int y) { this.x = x; this.y = y; } } class Test { static void Main() { Point[] points = new Point[100]; for (int i = 0; i < 100; i++) points[i] = new Point(i, i*i); } }

If Point is implemented as a struct, instead of classes, then the program creates just one object, for the array. The Point objects are allocated in-line within the array.
struct Point { public int x, y; public Point(int x, int y) { this.x = x; this.y = y; } } class Test { static void Main() { Point[] pointStruct = new Point[100]; for (int i = 0; i < 100; i++) pointStruct[i].Point(i, i*i); } }

58 4.7 INTERFACES

Chapter 4 - C# Language Specifications

The interface keyword declares a reference type that has abstract members. Interfaces are used to define a contract; a class or struct that implements the interface must obey to this contract. Interfaces can contain methods, properties, indexers, and events as members. They can not contain constants, fields (private data members), constructors and destructors or any type of static member. All the members of an interface are public by definition. The example
interface IExample { string this[int index] { get; set; } event EventHandler E; void Func(int value); string P { get; set; } } public delegate void EventHandler(object sender, EventArgs e);

shows an interface that contains an indexer, an event E, a method Func, and a property P. Interfaces may employ multiple inheritance. In the example
interface IControl { void Paint(); } interface ITextBox: IControl { void SetText(string text); } //ITextBox inherits IControl

interface IListBox: IControl //IListBox inherits IControl { void SetItems(string[] items); } interface IComboBox: ITextBox, IListBox {}

the interface IComboBox inherits from both ITextBox and IListBox. Classes and structs can implement multiple interfaces. In the example
interface IDataBound { void Bind(Binder b); }

BSIT 61 Basics of .NET

59

public class EditBox: Control, IControl, IDataBound { public void Paint() {...} public void Bind(Binder b) {...} }

the class EditBox derives from the class Control and implements both IControl and IDataBound. In the previous example, the Paint method from the IControl interface and the Bind method from IDataBound interface are implemented using public members on the EditBox class. C# provides an alternative way of implementing these methods that allows the implementing class to avoid having these members be public. Interface members can be implemented using a qualified name. For example, the EditBox class could instead be implemented by providing IControl.Paint and IDataBound.Bind methods.
public class EditBox: IControl, IDataBound { void IControl.Paint() {...} void IDataBound.Bind(Binder b) {...} }

Interface members implemented in this way are called explicit interface members because each member explicitly designates the interface member being implemented. Explicit interface members can only be called via the interface. For example, the EditBoxs implementation of the Paint method can be called only by casting to the IControl interface.
class Test { static void Main() { EditBox editbox = new EditBox(); editbox.Paint(); // error: no such method IControl control = editbox; control.Paint(); // calls EditBoxs Paint implementation } }

4.8 DELEGATES
A delegate is a C# language element that allow us to reference a method. For a C or C++ programmer, this is a familiar because a delegate is basically like a function pointer. However, unlike function pointers, delegates are object-oriented and type-safe. A delegate declaration defines a class that is derived from the class System.Delegate. A delegate instance encapsulates one or more methods, each of which is referred to as a callable entity. For instance

60

Chapter 4 - C# Language Specifications

methods, a callable entity consists of an instance and a method on that instance. For static methods, a callable entity consists of just a method. Given a delegate instance and an appropriate set of arguments, one can invoke all of that delegate instances methods with that set of arguments. An interesting and useful property of a delegate instance is that it does not know about the classes of the methods it encapsulates; all that matters is that those methods be compatible with the delegates type. This makes delegates perfectly suited for anonymous invocation. This is a powerful capability. There are three steps in defining and using delegates: declaration, instantiation, and invocation. Delegates are declared using delegate declaration syntax. The example
delegate void SimpleDelegate();

declares a delegate named SimpleDelegate that takes no arguments and returns no result. The example
class Test { static void F() { System.Console.WriteLine(Test.F); } static void Main() { SimpleDelegate dele = new SimpleDelegate(F); dele(); } }

creates a SimpleDelegate instance and then immediately calls it. There is not much point in instantiating a delegate for a method and then immediately calling that method via the delegate, as it would be simpler to call the method directly. Delegates really show their usefulness when their anonymity is used. The example
void MultiCall(SimpleDelegate dele, int count) { for (int i = 0; i < count; i++) { dele(); } }

BSIT 61 Basics of .NET

61

shows a MultiCall method that repeatedly calls a SimpleDelegate. The MultiCall method does not know or care about the type of the target method for the SimpleDelegate, what accessibility that method has, or whether or not that method is static. All that matters is that the target method is compatible with SimpleDelegate.

4.9 ENUMS
An enum type declaration defines a type name for a related group of symbolic constants. Enums are used for multiple choice, in which a runtime decision is made from a fixed number of choices that are known at compile-time. The example
enum Color { Red, Blue, Green } class Shape { public void Fill(Color color) { switch(color) { case:Color.Red: Console.WriteLine(RED); break; case:Color.Blue: Console.WriteLine(BLUE); break; case:Color.Green: Console.WriteLine(GREEN); break; default: break; } } }

shows a Color enum and a method that uses this enum. The signature of the Fill method makes it clear that the shape can be filled with one of the given colors. The use of enums is superior to the use of integer constants (as is common in languages without

62

Chapter 4 - C# Language Specifications

enums) because the use of enums makes the code more readable and self-documenting. The selfdocumenting nature of the code also makes it possible for the development tool to assist with code writing and other designer activities. For example, the use of Color rather than int for a parameter type enables smart code editors to suggest Color values.

4.10 NAMESPACES
C# programs are organized using namespaces. Namespaces are used both as an internal organization system for a program, and as an external organization system. This is a way of writing program elements that are exposed to other programs. A namespace declaration consists of the keyword namespace, followed by a namespace name and body.
namespace NamespaceName { ... // namespace body }

Classes actually contain data and Namespaces are used to logically arrange classes. Namespaces can also contain many other Namespaces and classes. C# programs are organized using namespaces. Namespaces provide a way to group classes, by providing an extra level of naming beyond the class name. Namespaces are implicitly public and the declaration of a namespace does not include any access modifiers. The identifier or name of a namespace may be a single identifier or a sequence of identifiers separated by . tokens. The later form permits a program to define a nested namespace. For example,
namespace ABC.XYZ { class A {} class B {} }

is equivalent to
namespace ABC { namespace XYZ { class A {} class B {} } }

BSIT 61 Basics of .NET

63

or it can also be written as


namespace ABC.XYZ { class A {} } namespace ABC.XYZ { class B {} }

All the above three fragments of code are equivalent. We know that the namespaces can be nested. Many namespaces in the base class library are nested. Prefixing each and every library calls with the namespace can get quite cumbersome. To avoid this over typing, use using statement. Let us see the below program which shows the usage of using statement
//Here is a program written without the using statement. public class Starter { static void Main() { System.Windows.Forms.MessageBox.Show(Hello, world!); System.Console.WriteLine(Hello, world); } } //This the same program written with the using statement. This is a //simpler one. using System; using System.Windows.Forms; public class Starter { static void Main() { MessageBox.Show(Hello, world!); Console.WriteLine(Hello, world); } }

4.11 ATTRIBUTES
C# is an imperative language, but like all imperative languages it does have some declarative elements.

64

Chapter 4 - C# Language Specifications

For example, the accessibility of a method in a class is specified by declaring it public, protected, internal, protected internal, or private. C# generalizes this capability, so that programmers can invent new kinds of declarative information, attach this declarative information to various program entities, and retrieve this declarative information at run-time. Programs specify this additional declarative information by defining and using attributes. For instance, a framework might define a HelpAttribute attribute that can be placed on program elements (such as classes and methods) enabling developers to provide a mapping from program elements to help documentation for them. The example
using System; public class HelpAttribute: Attribute { public HelpAttribute(string url) { this.url = url; } public string Topic = null; private string url; public string Url { get { return url; } } }

defines an attribute class named HelpAttribute, that has one positional parameter (string url) and one named parameter (string Topic). Positional parameters are defined by the formal parameters for public instance constructors of the attribute class, and named parameters are defined by public non-static readwrite fields and properties of the attribute class. The example
[Help(http://www.mycollege.com/.../Class1.htm)] public class Class1 { [Help(http://www.mycollege.com/.../Class1.htm, Topic = F)] public void F() {} }

shows several uses of the attribute Help. Attribute information for a given program element can be retrieved at run-time by using reflection support. The example

BSIT 61 Basics of .NET

65

using System; class Test { static void Main() { Type type = typeof(Class1); object[] arr = type.GetCustomAttributes(typeof(HelpAttribute), true); if (arr.Length == 0) Console.WriteLine(Class1 has no Help attribute.); else { HelpAttribute ha = (HelpAttribute) arr[0]; Console.WriteLine(Url={0}, Topic={1}, ha.Url, ha.Topic); } } }

checks to see if Class1 has a HelpAttribute, and writes to the console the associated Topic and Url values if the attribute is present.

SUMMARY
This chapter covers the C# language specification. In C# language two categories of types - Value types and Reference types. There are seven categories of C# variables - Static variables, Instance variables, Array elements, Value parameters, Reference parameters, Output parameters and Local variables. The expressions and statements are same as in C++, except foreach looping statement which iterate over the elements in arrays and collections. Structs are similar to classes, it also contains data members and function members. Except Structs are value types and Classes are reference type. Interfaces are reference types which are used to implement multiple inheritance. A delegate allows us to reference a method. C# programs are organized using namespaces. Namespaces are used both as an internal organization system for a program, and as an external organization system. In C# additional declarative information by defining and using attributes.

QUESTIONS
1. 2. 3. 4. 5. Which are two different categories of types in C#? What are variables? How many categories of variables are there in C#? Define each. What is the importance of automatic memory management? Explain with example. Write a note on expressions and operators in C#. What are empty statement and labeled statements? Why are they used?

66
6. 7. 8. 9.

Chapter 4 - C# Language Specifications

What is an iterative statement? Explain foreach statement with example. Which are different jump statements supported by C#? What are checked and unchecked statements? Give example. Give an example lock and using statements.

10. How are structures different from classes in C#? 11. What are interfaces? Give an example.

12. What is a delegate? What is the use of it? Give example 13. Write a program to demonstrate the usage of enums in C#. 14. Write a note on namespaces in C#. 15. What is the use of attributes in C# programs?

BSIT 61 Basics of .NET

67

Chapter 5

Classes And Inheritance

By the end of this chapter, you will 8 8 8 Be knowledged with the classes in C# Know how to implement inheritance in C# Know method overloading concept

5.1 CLASSES
Class declarations are reference types. A class can inherit from another class, and can implement interfaces. Class members can include constants, fields, methods, properties, events, indexers, operators, instance constructors, destructors, static constructors, and nested type declarations. Each member has an associated accessibility, which controls the portion of program code that is able to access the member. There are five forms of accessibility. They are summarized in the table below.

Accessibility Intuitive meaning public Access not limited Access limited to the containing class or types derived from the protected containing class internal Access limited to the program protected Access limited to the program or types derived from the containing class internal private Access limited to the containing type
Table 5.1 : Accessibility forms

BSIT 61 Basics of .NET

67

68

Chapter 5 - Classes And Inheritance

The declared accessibility of a member can be one of the following:


l

Public, which is selected by including a public modifier in the member declaration. The intuitive meaning of public is access not limited. Protected internal (meaning protected or internal), which is selected by including both a protected and an internal modifier in the member declaration. The intuitive meaning of protected internal is access limited to this program or types derived from the containing class. Protected, which is selected by including a protected modifier in the member declaration. The intuitive meaning of protected is access limited to the containing class or types derived from the containing class. Internal, which is selected by including an internal modifier in the member declaration. The intuitive meaning of internal is access limited to the program. Private, which is selected by including a private modifier in the member declaration. The intuitive meaning of private is access limited to the containing type.

The example
using System; class MyClass { public MyClass() // Instance constructor { Console.WriteLine(Instance constructor); } public MyClass(int value) // Parameterized Instance constructor { MyField = value; Console.WriteLine(Instance constructor); } ~MyClass() // Destructor { Console.WriteLine(Destructor); } public const int MyConst = 20; public int MyField = 40; public void MyMethod() { Console.WriteLine(MyClass.MyMethod); }

BSIT 61 Basics of .NET

69

public int MyProperty { get { return MyField; } set { MyField = value; } } public int this[int index] { get { return 0; } set { Console.WriteLine(this[{0}] = {1}, index, value); } } public event EventHandler MyEvent; public static MyClass operator+(MyClass a, MyClass b) { return new MyClass(a.MyField + b.MyField); } internal class MyNestedClass {} }

shows a class that contains properties, constant, field, event, indexed and method as members. The below class, containing Main method, shows uses of these members.
class Test { static void Main() { // Instance constructor usage MyClass a = new MyClass(); MyClass b = new MyClass(123); // Constant usage Console.WriteLine(MyConst = {0}, MyClass.MyConst);

70

Chapter 5 - Classes And Inheritance

// Field usage a.MyField++; Console.WriteLine(a.MyField = {0}, a.MyField); // Method usage a.MyMethod(); // Property usage a.MyProperty++; Console.WriteLine(a.MyProperty = {0}, a.MyProperty); // Indexer usage a[3] = a[1] = a[2]; Console.WriteLine(a[3] = {0}, a[3]); // Event usage a.MyEvent += new EventHandler(MyHandler); // Overloaded operator usage MyClass c = a + b; } static void MyHandler(object sender, EventArgs e) { Console.WriteLine(Test.MyHandler); } internal class MyNestedClass {} }

The class members properties, constant, field, event, indexed and method are explained in the following topics.

5.2 CONSTANTS
A constant is a class member that represents a constant value. Constant members are initialized at the time of their declaration. The example
class Constants { public const int A = 1; public const int B = A + 1; }

shows a class named Constants that has two public constants.

BSIT 61 Basics of .NET

71

Constants are considered static members, but constant declaration does not requires the static modifier. Constants can be accessed through the class, as in
using System; class Test { static void Main() { Console.WriteLine({0}, {1}, Constants.A, Constants.B); } }

which prints out the values of Constants.A and Constants.B, respectively.

5.3 FIELDS
A field is a member that represents a variable associated with an object or class. The example
class Color { internal ushort redPart; internal ushort bluePart; internal ushort greenPart; public Color(ushort red, ushort blue, ushort green) { redPart = red; bluePart = blue; greenPart = green; } public public public public } static static static static Color Color Color Color Red = new Color(0xFF, 0, 0); Blue = new Color(0, 0xFF, 0); Green = new Color(0, 0, 0xFF); White = new Color(0xFF, 0xFF, 0xFF);

shows a Color class that has internal instance fields named redPart, bluePart, and greenPart, and static fields named Red, Blue, Green, and White. The use of static fields in this manner is not ideal. The fields are initialized at some point before they are used, but after this initialization they can be changed. Such a modification to the fields could cause unpredictable errors in other programs that use Color and assume that the values do not change. Readonly fields can be used to prevent such problems. Assignments to a readonly field can only occur as part of the declaration, or in an instance constructor or static

72

Chapter 5 - Classes And Inheritance

constructor in the same class. A static readonly field can be assigned in a static constructor, and a nonstatic readonly field can be assigned in an instance constructor. Thus, the Color class can be enhanced by adding the modifier readonly to the static fields as shown below
class Color { internal ushort redPart; internal ushort bluePart; internal ushort greenPart; public Color(ushort red, ushort blue, ushort green) { redPart = red; bluePart = blue; greenPart = green; } public public public public } static static static static readonly readonly readonly readonly Color Color Color Color Red = new Color(0xFF, 0, 0); Blue = new Color(0, 0xFF, 0); Green = new Color(0, 0, 0xFF); White = new Color(0xFF, 0xFF, 0xFF);

5.4 METHODS
A method is a member that implements a computation or action that can be performed by an object or class. Methods have a list of formal parameters, a return value and are either static or non-static. Static methods are accessed through the class. Non-static methods, which are also called instance methods, are accessed through instances of the class (objects). The example
using System; public class Stack { public static Stack Clone(Stack s) {...} public static Stack Flip(Stack s) {...} public object Pop() {...} public void Push(object o) {...} public override string ToString() {...} ... } class Test

BSIT 61 Basics of .NET

73

{ static void Main() { Stack s = new Stack(); for (int i = 1; i < 10; i++) s.Push(i); Stack flipped = Stack.Flip(s); Stack cloned = Stack.Clone(s); Console.WriteLine(Original stack: + s.ToString()); Console.WriteLine(Flipped stack: + flipped.ToString()); Console.WriteLine(Cloned stack: + cloned.ToString()); } }

shows a Stack that has several static methods (Clone and Flip) and several instance methods (Pop, Push, and ToString). Methods can be overloaded, which means that multiple methods may have the same name. The method with matching signature is called. The signature of a method consists of the name of the method and the number, modifiers, and types of its formal parameters. The signature of a method does not include the return type. The example
using System; class Test { static void Func() { Console.WriteLine(Func()); } static void Func(object o) { Console.WriteLine(Func(object)); } static void Func(int value) { Console.WriteLine(Func(int)); } static void Func(ref int value) { Console.WriteLine(Func(ref int)); } static void Func(int a, int b)

74
{ Console.WriteLine(Func(int, int)); } static void Func(int[] values) { Console.WriteLine(Func(int[])); } static void Main() { Func(); Func(1); int i = 10; Func(ref i); Func((object)1); Func(1, 2); Func(new int[] {1, 2, 3}); } }

Chapter 5 - Classes And Inheritance

shows a class with a number of methods called Func. The output produced is
Func() Func(int) Func(ref int) Func(object) Func(int, int) Func(int[])

Parameter Passing
Passing by value - The parameter modifiers ref and out relate to how the parameter is passed into the method. Where neither of these modifiers is used, the parameter is passed in by value. In this case, when the method is called the value given is copied to the variable specified in the method declaration. The following example illustrates this point; note that the change made to variable b in the body of the change method does not result in a change to the variable a used to invoke the method.
public static void Main() { int a = 0; change(a); } public static void change(int b) { b = 5; }

BSIT 61 Basics of .NET

75

In this example, it was a value type that was passed by value. But reference types can also be passed by value. We know that, reference type variable is actually holds a memory address. So when this variable is passed by value, the memory address is copied to the variable specified in the method. But of course, because the two variables will hold the same memory address, any changes made within the method body to the object located at that memory address will be reflected outside the method. Passing by reference - In C# we can pass variables into methods by reference. Where a variable is passed by reference, the ref modifier must be used both in the method definition argument list and the method invocation. Passing by reference is most obviously useful in cases where we want to treat a value type like a reference type. For instance, the method call in the following code does change the value of the variable a passed into the change method.
public static void Main() { int a = 0; change(ref a); // After this method invocation, a=5 } public static void change (ref int b) { b = 5; }

output parameters - Where a method parameter is defined (and invoked) using the out modifier, it is passed by reference. The difference between the out and the ref modifier is this: a parameter modified by the out keyword need not be assigned a value before being passed into the method, but must be assigned a value in the method before it is returned. The reason that one might use output parameters is to return multiple values from a method. For instance, in the following code an integer and a boolean is passed to the change method. This method sets the boolean to indicate whether or not the integer is greater than 0, and returns the value of the integer doubled. So here both boolean and interger result is returned from the method.
public static void Main() { bool b; int c = change(5, out b); } public static int change (int a, out bool b) { b=false; if (a>0) b=true; return (2*a); }

76

Chapter 5 - Classes And Inheritance

The params modifier - One can pass an arbitrary number of types to a method by declaring a parameter array with the params modifier. Note, though, that it is not necessary to place these additional types into an array before calling the method, they can simply be listed in the method invocation. Types passed as params are all passed by value. The following code gives an example of the use of the params modifier.
public static void Main() { double a = 1; int b = 2; int c = 3; int d = 4; int e = total(a, b, c, d); } public static int total(double a, params int[] intArr) { int sum = 0; for (int i=0; i < intArr.Length; i++) sum += intArr[i]; return sum; }

The method called ignores the first type passed to it (a double) and returns the sum of all (an arbitrary number of) the integer values (b, c and d) passed to it. The param array intArr holds b, c and d values in it. Return Type - Methods can either return a type or not. A method that does not return a type must give its return type as void. A method that does return a type must name the type returned. A method will stop executing and return a value when it reaches a return statement at any point in its execution. The type returned is given at the end of such a return statement; its type must correspond with the type specified in the method declaration. For example, the following piece of code illustrates this point.
public static int exampleMethod() { int i = 0; ... return i; }

BSIT 61 Basics of .NET

77

5.5 PROPERTIES
A property is a member that provides access to a characteristic of an object or a class. Examples of properties include the length of a string, the size of a font, the caption of a window, the name of a customer, and so on. Properties are a natural extension of fields. Both are named members with associated types, and the syntax for accessing fields and properties is the same. However, unlike fields, properties do not denote storage locations. Instead, properties have accessors that specify the block of statements to be executed when their values are read or written. Properties are defined with property declarations. The first part of a property declaration looks quite similar to a field declaration. The second part includes a get accessor or a set accessor. In the example below, the Button class defines a Caption property.
public class Button { private string caption; public string Caption { get // get accessor block { return caption; } set // set accessor block { caption = value; Repaint(); } } }

Properties that can be both read and written, such as Caption, include both get and set accessors. The get accessor is called when the propertys value is read and the set accessor is called when the propertys value is written. The declaration of properties is relatively straightforward, but the real value of properties is seen when they are used. For example, the Caption property can be read and written in the same way that fields can be read and written:
Button b = new Button(); b.Caption = ABC; // set accessor executed string s = b.Caption; // get accessor is executed b.Caption += DEF; // get & set accessor both are executed

78 5.6 EVENTS

Chapter 5 - Classes And Inheritance

An event is a member that enables an object or class to provide notifications. A class defines an event by providing an event declaration and an optional set of event accessors. The declaration resembles a field declaration, though with an added event keyword. The type of this declaration must be a delegate type. An instance of a delegate type encapsulates one or more callable entities. For instance methods, a callable entity consists of an instance and a method on that instance. For static methods, a callable entity consists of just a method. Given a delegate instance and an appropriate set of arguments, one can invoke all of that delegate instances methods with that set of arguments. In the example
public delegate void EventHandler(object sender, System.EventArgs e); public class Button { public event EventHandler Click; public void Reset() { Click = null; } }

the Button class defines a Click event of type EventHandler. Inside the Button class, the Click member is exactly like a private field of type EventHandler. However, outside the Button class, the Click member can only be used on the left-hand side of the += and -= operators. The += operator adds a handler for the event, and the -= operator removes a handler for the event. Let us take an example, where we have a form and a button on the form. Whenever the button is clicked, that click event has to be identified and message Button1 was clicked! must be displayed.
using System; public class Form1 { public Form1() { //Add Button1_Click as event handler for Button1s Click event Button1.Click += new EventHandler(Button1_Click); } Button Button1 = new Button(); void Button1_Click(object sender, EventArgs e)

BSIT 61 Basics of .NET

79

{ Console.WriteLine(Button1 was clicked!); } public void Disconnect() { Button1.Click -= new EventHandler(Button1_Click); } }

shows a Form1 class that adds Button1_Click as an event handler for Button1s Click event. In the Disconnect method, that event handler is removed. For a simple event declaration such as
public event EventHandler Click;

the compiler automatically provides the implementation underlying the += and -= operators. An implementer who wants more control can get it by explicitly providing add and remove accessors. For example, the Button class could be rewritten as follows:
public class Button { private EventHandler handler; public event EventHandler Click { add { handler += value; } remove { handler -= value; } } }

This change has no effect on calling code, but allows the Button class more implementation flexibility. For example, the event handler for Click need not be represented by a field.

5.7 INDEXERS
An indexer enables an object to be indexed in the same way as an array. Whereas properties enable field-like access, indexers enable array-like access. As an example, consider the Stack class presented earlier. The designer of this class might want to use array like access so that it is possible to manipulate the items on the stack without performing unnecessary Push and Pop operations. That is, class Stack is implemented as a linked list, but it also provides the convenience of array access.

80

Chapter 5 - Classes And Inheritance

Indexer declarations are similar to property declarations, with the main differences being that indexers are nameless and that indexers include indexing parameters. The indexing parameters are provided between square brackets. The example
using System; public class Stack { private Node GetNode(int index) { Node temp = first; while (index > 0) { temp = temp.Next; index ; } return temp; } public object this[int index] { get { if (!ValidIndex(index)) throw new Exception(Index out of range.); else return GetNode(index).Value; } set { if (!ValidIndex(index)) throw new Exception(Index out of range.); else GetNode(index).Value = value; } } ... } class Test { static void Main() { Stack s = new Stack(); s.Push(1); s.Push(2); s.Push(3);

BSIT 61 Basics of .NET

81
// Changes the top item from 3 to 33 // Changes the middle item from 2 to 22 // Changes the bottom item from 1 to 11

s[0] = 33; s[1] = 22; s[2] = 11; } }

shows an indexer for the Stack class.

5.8 INSTANCE CONSTRUCTORS


An instance constructor is a member that implements the actions required to initialize an instance of a class. The example
using System; class Point { public double x, y; // Instance constructor public Point() { this.x = 0; this.y = 0; } //Parameterized Instance constructor public Point(double x, double y) { this.x = x; this.y = y; } public static double Distance(Point a, Point b) { double xdiff = a.x - b.x; double ydiff = a.y - b.y; return Math.Sqrt(xdiff * xdiff + ydiff * ydiff); } public override string ToString() { return string.Format(({0}, {1}), x, y); } }

82

Chapter 5 - Classes And Inheritance

class Test { static void Main() { Point a = new Point(); Point b = new Point(3, 4); double d = Point.Distance(a, b); Console.WriteLine(Distance from {0} to {1} is {2}, a, b, d); } }

shows a Point class that provides two public instance constructors, one of which takes no arguments, while the other takes two double arguments. If no instance constructor is supplied for a class, then an empty one with no parameters is automatically provided.

5.9 DESTRUCTORS
A destructor is a member that implements the actions required to destruct an instance of a class. Destructors cannot have parameters, they cannot have accessibility modifiers, and they cannot be called explicitly. The destructor for an instance is called automatically during garbage collection. The example
using System; class Point { public double x, y; public Point(double x, double y) { this.x = x; this.y = y; } ~Point() { Console.WriteLine(Destructed {0}, this); } public override string ToString() { return string.Format(({0}, {1}), x, y); } }

shows a Point class with a destructor.

BSIT 61 Basics of .NET

83

5.10 STATIC CONSTRUCTORS


A static constructor is a member that implements the actions required to initialize a class. Static constructors cannot have parameters, they cannot have accessibility modifiers, and they cannot be called explicitly. The static constructor for a class is called automatically. The example
class Employee { private static DataSet ds; static Employee() { ds = new DataSet(...); } public string Name; public decimal Salary; ... }

shows an Employee class with a static constructor that initializes a static field.

5.11 INHERITANCE
C# classes support single inheritance, and the type object is the ultimate base class for all classes. The classes shown in earlier examples all implicitly derive from object. The example
using System; class A { public void F() { Console.WriteLine(Inside A.F); } }

shows a class A that implicitly derives from object. The example


class B: A { public void G() { Console.WriteLine(Inside B.G); } } class Test {

84
static void Main() { B b = new B(); b.F(); // Inherited from A b.G(); // Introduced in B A a = b; a.F(); } } // Treat a B as an A

Chapter 5 - Classes And Inheritance

The output will be


Inside A.F Inside B.G Inside A.F

shows a class B that derives from A. The class B inherits As F method, and introduces a G method of its own. Methods, properties, and indexers can be virtual, which means that their implementation can be overridden in derived classes. The example
using System; class A { public virtual void F() { Console.WriteLine(A.F); } } class B: A { public override void F() { base.F(); Console.WriteLine(B.F); } } class Test { static void Main() { B b = new B(); b.F(); A a = b; a.F(); } }

BSIT 61 Basics of .NET

85

The output will be


A.F B.F A.F B.F

shows a class A with a virtual method F, and a class B that overrides F. The overriding method in B contains a call, base.F(), which calls the overridden method in A. A class can indicate that it is incomplete, and is intended only as a base class for other classes, by including the modifier abstract. Such a class is called an abstract class. An abstract class can specify abstract members. These abstract members are members that a non-abstract derived class must implement. The example
using System; abstract class A { public abstract void F(); } class B: A { public override void F() { Console.WriteLine(B.F); } } class Test { static void Main() { B b = new B(); b.F(); A a = b; a.F(); } }

The output will be


B.F B.F

introduces an abstract method F in the abstract class A. The non-abstract class B provides an implementation for this method.

86 5.12 METHOD OVERLOADING

Chapter 5 - Classes And Inheritance

Each method has a signature. The signature comprises the methods name and its parameters but not the methods return type. In the following method header, the elements making up the methods signature are emphasised. Note also that the params keyword is not included in the signature. public static int myMethod(int a, ref double b, out bool c, params int[] d) The importance of the signature is that no class is allowed to contain two methods with the same signature. Since the signature takes in more than the method name, however, it is possible for one class to have methods sharing a name. For example, a class with the method whose header is given above might also contain a method with the header: public static int myMethod(int a, ref double b) Note, however, that since neither its return type nor the params keyword are part of a methods signature this class could not also contain a method with the header given below: public static void myMethod(int e,ref double f,out bool g,int[] h)

5.13 OPERATOR OVERLOADING


To overload an operator in a class, one defines a method using the operator keyword. For instance, the following code overloads the equality operator
public static bool operator == ( Value a ,Value b) { return a.Int == b.Int }

If an operator is one of a logical pair, both operators should be overwritten if any one is overloaded. These pairs are the following:
== and != < and > <= and >=

To understand the need for operator overloading, imagine that we need to perform matrix addition or multiplication operations in our program. We could instantiate 2 2-dimensional arrays. However, add the requirement for the matrix behavior to be reusable. Because we need to do the same thing in other programs and want to take advantage of the fact that we have already written the code, we want to create a new type. So, we create a Matrix type, which could be a class or a struct. We have to initialize two or more

BSIT 61 Basics of .NET

87

Matrix instances with data and then do a mathematical operation with them, such as add or multiply. To accomplish the mathematical operation, we implement an Add(), DotProduct(), and other methods to get the job done. Using the classes would look something like this:
Matrix result = mat1.Add(mat2); // instance

or
Matrix result = Matrix.Add(mat1, mat2); // static

or event worse
Matrix result = mat1.DotProduct(mat2).DotProduct(mat3); // and so on...

The problem with using methods like this is that it is cumbersome, verbose, and unnatural for the problem we are trying to solve. It would be much easier to have a + operator for the add operation and a * operator for the dot product operation. The following shows how the syntax appears using operators:
Matrix result = mat1 + mat2;

or
Matrix result = mat1 * mat2;

or even better
Matrix result = mat1 * mat2 * mat3 * mat4;

This is much more elegant and easier to work with. For a single operation, one could argue that the amount of work to implement it is not that great. However, for chain of multiple mathematical operations, the syntax is much simpler. Additionally, if the primary users are mathematicians and scientists, operators are more intuitive and natural.

Implementing an Overloaded Operator


The syntax required to implement an overloaded operator is much the same as a static method with a couple exceptions. We must use the operator keyword and specify the operator symbol being overloaded. Here is a skeleton example of how the * operator could be implemented:
public static Matrix operator *(Matrix mat1, Matrix mat2) { // dot product implementation }

Notice that the method is static. Use the keyword operator after specifying the return type, Matrix in this case. Following the operator keyword, the actual operator symbol is specified and then there is a set

88

Chapter 5 - Classes And Inheritance

of parameters to be operated on. Let us see example code of how to implement and use an overloaded operator. //Implementing Overloaded Operator
using System; class Matrix3D { // its a 3D matrix public const int DIMSIZE = 3; private double[,] matrix = new double[DIMSIZE, DIMSIZE]; // allow callers to initialize public double this[int x, int y] { get { return matrix[x, y]; } set { matrix[x, y] = value; } } // let user add matrices public static Matrix3D operator +(Matrix3D mat1, Matrix3D mat2) { Matrix3D newMatrix = new Matrix3D(); for (int x=0; x < DIMSIZE; x++) for (int y=0; y < DIMSIZE; y++) newMatrix[x, y] = mat1[x, y] + mat2[x, y]; return newMatrix; } } class MatrixTest { // used in the InitMatrix method. public static Random rand = new Random(); // test Matrix3D static void Main() { Matrix3D mat1 = new Matrix3D(); Matrix3D mat2 = new Matrix3D(); // init matrices with random values InitMatrix(mat1); InitMatrix(mat2);

BSIT 61 Basics of .NET

89

// print out matrices Console.WriteLine(Matrix 1: ); PrintMatrix(mat1); Console.WriteLine(Matrix 2: ); PrintMatrix(mat2); // perform operation and print out results Matrix3D mat3 = mat1 + mat2; Console.WriteLine(); Console.WriteLine(Matrix 1 + Matrix 2 = ); PrintMatrix(mat3); } // initialize matrix with random values public static void InitMatrix(Matrix3D mat) { for (int x=0; x < Matrix3D.DIMSIZE; x++) for (int y=0; y < Matrix3D.DIMSIZE; y++) mat[x, y] = rand.NextDouble()*10; } // print matrix to console public static void PrintMatrix(Matrix3D mat) { Console.WriteLine(); for (int x=0; x < Matrix3D.DIMSIZE; x++) { Console.Write([ ); for (int y=0; y < Matrix3D.DIMSIZE; y++) { // format the output Console.Write({0,8:#.00}, mat[x, y]); if ((y+1 % 2) < 3) Console.Write(, ); } Console.WriteLine( ]); } Console.WriteLine(); } }

90
The output will be
Matrix 1: [ [ [ 5.40, 7.08, .42, 9.89, 4.63, 5.14, 5.47 ] .70 ] 5.96 ]

Chapter 5 - Classes And Inheritance

Matrix 2: [ [ [ 9.95, 8.42, 3.57, 8.76, 4.43, 7.69, 5.35 ] 7.53 ] 3.60 ]

Matrix 1 + Matrix 2 = [ [ [ 15.35, 15.50, 3.99, 18.66, 9.07, 12.83, 10.82 ] 8.23 ] 9.56 ]

Similar to the skeleton example of the dot product operator, the Matrix class contains an operator overload for the + operator

Operator Rules
C# enforces certain rules when you overload operators. One rule is that you must implement the operator overload in the type that will use it. This is sensible because it makes the type self-contained. Another rule is that you must implement matching operators. For example, if you overload ==, you must also implement !=. The same goes for <= and >=. When you implement an operator, its compound operator also works. For example, since the + operator for the Matrix3D type was implemented, you can also use the += operator on Matrix3D types.

SUMMARY
Classes are reference types. Members of class can be constants, fields, methods, properties, events, indexers, operators, instance constructors, destructors, static constructors, and nested type declarations. There are five forms of accessibility public, protected, internal, protected internal and private. A constant represents a constant value and they are initialized at the time of their declaration. A field is a member that represents a variable associated with an object or class. Methods can be static or nonstatic. Static methods are accessed through the class. Non-static methods are accessed through instances of the class. A property is a member that provides access to a characteristic of an object or a class. An event is a member that enables an object to provide notification. An indexer enables an object to be

BSIT 61 Basics of .NET

91

indexed in the same way as an array. An instance constructor is a member that initializes an instance of a class. A destructor is a member that destructs an instance of a class. A static constructor is a member that initializes a class. C# classes support single inheritance, and the System.Object is the ultimate base class for all classes. Method and operators can be overloaded in C#.

QUESTIONS
1. 2. 3. 4. 5. 6. 7. 8. Write a note on classes in C#. What are constant members? Give an example. Give an example of field member. With appropriate examples explain parameter passing in C#. What is the use of property member in a class? What are events? Give an example to demonstrate its usage. With an example explain indexers. Explain each with an example a. b. c. 9. Instance constructors Destructor Static constructor

How does C# supports inheritance?

10. What is method overloading? Give an example. 11. What is operator overloading? Give an example.

92
Chapter 6

Chapter 6 - Advanced C#

Advanced C#

By the end of this chapter, you will 8 8 8 8 Explore C# preprocessor directives Learn how to handle exception Know unsafe code concept Threading

6.1 C# PREPROCESSOR DIRECTIVES


In this section we will discusses about the C# language preprocessor directives. While the compiler does not have a separate preprocessor, the directives are processed as if there was a preprocessor. These directives are used during conditional compilation. Unlike C and C++ directives, we cannot use these directives to create macros. A preprocessor directive must be the only instruction on a line. We will discuss about each of them.

#if
#if, begins a conditional directive for testing a symbol, to see if they evaluate to true. If they do evaluate to true, the compiler evaluates all the code between the #if and the next corresponding directive. The following operators can also be used to evaluate multiple symbols, like

92

Chapter 6 - Advanced C#

BSIT 61 Basics of .NET

93

== (equality symbol) != (inequality symbol) && (and symbol) || (or symbol) #if, along with the #else, #elif, #endif, #define, and #undef directives, can be used to include or exclude code based on the condition of one or more symbols. A conditional directive beginning with a #if directive must explicitly be terminated with a #endif, directive. For example,
#define DEBUG #define VC_V6 using System; public class MyClass { public static void Main() { #if (DEBUG && !VC_V6) Console.WriteLine("DEBUG #elif (!DEBUG && VC_V6) Console.WriteLine("VC_V6 #elif (DEBUG && VC_V6) Console.WriteLine("DEBUG #else Console.WriteLine("DEBUG #endif } }

is defined"); is defined"); and VC_V6 are defined"); and VC_V6 are not defined");

The output will be, DEBUG and VC_V6 are defined

#else
#else, creates a compound conditional directive, such that, if none of the expressions in the preceding #if or #elif directives did not evaluate to true, the compiler will evaluate all code between #else and the subsequent #endif.

#elif
#elif, creates a compound conditional directive, it evaluates if neither the preceding #if nor any preceding

94

Chapter 6 - Advanced C#

#elif directive expressions evaluate to true. If a #elif expression evaluates to true, the compiler evaluates all the code between the #elif and the next corresponding directive. #elif is equivalent to using #else and then #if. But using #elif is simpler because each #if requires a #endif, whereas a #elif can be used without a matching #endif.

#endif
#endif specifies the end of a conditional directive, which began with the #if directive.

#define
#define, defines a symbol by using the symbol as the expression passed to the #if directive, the expression will evaluate to true.

#undef
#undef, undefines a symbol by using the symbol as the expression in a #if directive, the expression will evaluate to false. The #undef directive must appear in the file before we use any statements that are not directives. For example,
#undef DEBUG using System; public class MyClass { public static void Main() { #if DEBUG Console.WriteLine("DEBUG is defined"); #else Console.WriteLine("DEBUG is not defined"); #endif } }

The output will be, DEBUG is not defined

#warning
#warning, generates a level one warning from a specific location in our code. A common use of #warning is in a conditional directive.

BSIT 61 Basics of .NET

95

For example,
#define DEBUG public class MyClass { public static void Main() { #if DEBUG #warning DEBUG is defined #endif } }

#error
#error, generates an error from a specific location in your code. A common use of #error is in a conditional directive. For example,
#define DEBUG public class MyClass { public static void Main() { #if DEBUG #error DEBUG is defined #endif } }

#line
#line, modifies the compilers line number and the file name output for errors and warnings. A source code file may have any number of #line directives. For example,
public class MyClass2 { public static void Main() { #line 200 int i; // error or warning will be: CS0168 on line 200 #line 8 char c; // error or warning will be: CS0168 on line 8 } }

96 6.2 EXCEPTION HANDLING

Chapter 6 - Advanced C#

An exception is any error condition or unexpected behavior encountered by a program in execution. Exceptions can be raised because of a fault in our code or in shared library or when operating system resources not being available or when unexpected conditions the CLR encounters and so on. If the application does not handle these exception, then the application terminates (default behavior). In the .NET Framework, an exception is an object that inherits from the ExceptionClass class. An exception object is thrown from an area of code where an exception has occurred. If the thrown exception is not caught then the application program terminates. Exceptions in C# provide a structured way of handling both system level and application level error conditions. The exception mechanism is C# is quite similar to C++ exception handling mechanism, with a few important differences which are:
l

In C++, any type value can be used to represent an exception. In C#, all exceptions must be represented by an instance of a class type derived from System.Exception. In C#, a finally block can be used to write termination code which executes in both normal execution and exceptional conditions. Such code is difficult in C++. In C#, system-level exceptions such as overflow, divide-by-zero, and null de-references have well defined exception.

Here is a C# example, which demonstrates the usage of try, catch, throw and finally statements.
using System; using System.IO; public class ProcessFile { public static void Main() { try //Opens a text file. { FileStream fs = new FileStream(data.txt, FileMode.Open); StreamReader sr = new StreamReader(fs); string line; //Read from the file and output it to the console. line = sr.ReadLine(); Console.WriteLine(line); } catch(FileNotFoundException e) { Console.WriteLine([Data File Missing] {0}, e); throw new FileNotFoundException(data.txt not exists,e);

BSIT 61 Basics of .NET

97

} finally { fs.Close(); } } }

If the data.txt file exists then, the out put will be


This is data.txt file Reached Finally block

If the data.txt file does not exists then, the out put will be
[Data File Missing] System.IO.FileNotFoundException: Could not find file E:\Bhagya\CSharpnotes\Program\Programs\bin\Debug\data.txt. File name: E:\Bhagya\CSharpnotes\Program\Programs\bin\Debug\data.txt at System.IO.__Error.WinIOError(Int32 errorCode, String str) at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean useAsync, String msgPath, Boolean bFromProxy) at System.IO.FileStream..ctor(String path, FileMode mode) at ProcessFile.Main() in e:\bhagya\CSharpnotes\program\programs\class1.cs:line 10 Throw the exception again Unhandled Exception: System.IO.FileNotFoundException: data.txt not exists > System.IO.FileNotFoundException: Could not find file E:\Bhagya\C Sharp notes\Program\Programs\bin\Debug\data.txt. File name: E:\Bhagya\CSharpnotes\Program\Programs\bin\Debug\data.txt at System.IO.__Error.WinIOError(Int32 errorCode, String str) at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, Boolean useAsync, String msgPath, Boolean bFromProxy) at System.IO.FileStream..ctor(String path, FileMode mode) at ProcessFile.Main() in e:\bhagya\CSharpnotes\program\programs\class1.cs:line 10 at ProcessFile.Main() in e:\bhagya\CSharpnotes\program\programs\class1.cs:line 24 Reached Finally block

98

Chapter 6 - Advanced C#

Place the section of code that might throw exceptions in a try block and place code that handles exceptions in a catch block. The catch block is a series of statements beginning with the keyword catch, followed by an exception type and an action to be taken. We can explicitly throw an exception using the throw statement. A finally block is always executed, regardless of whether an exception is thrown. The following example uses a try/catch block to catch a FileNotFoundException. Catch block catches the FileNotFoundException and writes a message to the console if the data file is not found. The next statement is the throw statement that throws a new FileNotFoundException, which is not handle in further. The text information about the exception is printed on console.

Causes of exceptions
Exception can be thrown in two different following ways. 1. A throw statement throws an exception immediately and unconditionally. Control will not reach the statement immediately following the throw. 2. Certain exceptional conditions that arise during the processing of C# statements cause an exception in certain circumstances when the operation cannot be completed normally. For example, an integer division operation throws a System.DivideByZeroException if the denominator is zero.

The System.Exception class


The System.Exception is the base class for all exceptions. Few common properties that all exceptions share are:
l l

Message, which is a read-only string that contains a description of the the exception. InnerException, is a read-only Exception. If it is a non-null value, it refers to the exception that caused the current exception. Otherwise, if value is null, that indicates that this exception was not caused by exception.

The value of these properties can be specified in calls to the instance constructor for System.Exception.

How exceptions are handled


Exceptions are handled by a try statement. When an exception occurs, the system searches for the nearest catch block that can handle the exception. Once a matching catch block is found, the control is transferred to the first statement of the catch block and the catch block executes. If no matching catch block or finally block is found, then the execution of the thread is terminated. The following exception objects are thrown when corresponding exception occurs.

BSIT 61 Basics of .NET

99
A base class for exceptions that occur during arithmetic operations, like System.DivideByZeroException and System.OverflowException. Thrown when a store into an array fails because the stored element is incompatible with the actual type of the array. Thrown when an attempt to divide an integer value by zero is made. Thrown when an attempt to index an array via an index that is less than zero or outside the bounds occurs. Thrown when an explicit conversion from a base type or interface to a derived types fails at run time. Thrown when an attempt to combine two non-null delegates fails, because the delegate type does not have a void return type. Thrown when a null reference is used in a way that causes the referenced object to be required. Thrown when an attempt to allocate memory (new) fails. Thrown when an arithmetic operation in a checked block overflows. Thrown when the execution stack is exhausted by having too many pending method calls. Thrown when a static constructor throws an exception, and no catch block exists to catch it.

System.ArithmeticException

System.ArrayTypeMismatchException

System.DivideByZeroException System.IndexOutOfRangeException

System.InvalidCastException

System.MulticastNotSupportedException

System.NullReferenceException

System.OutOfMemoryException System.OverflowException System.StackOverflowException

System.TypeInitializationException

Table 6.1 : List of Common Exception Classes

6.3 UNSAFE CODE


The C# language has omitted pointers as a data type. C# instead provides references and the ability to

100

Chapter 6 - Advanced C#

create objects that are managed by a garbage collector. This design contributes in making C# a much safer language than C or C++. In the core C# language it is simply not possible to have an uninitialized variable, a dangling pointer, or an expression that indexes an array beyond its bounds. These categories are main cause of bugs in C and C++ programs, so are eliminated here. While practically every pointer type construct in C or C++ has a reference type counterpart in C#, there are situations where access to pointer types becomes a necessity. For example, interfacing with the underlying operating system, accessing a memory-mapped device, or implementing a time-critical algorithm may not be possible without access to pointers. To address this need, C# provides the ability to write unsafe code. In unsafe code it is possible to declare and operate on pointers, to perform conversions between pointers and integral types, to take the address of variables, and so forth. In a sense, it is like writing C code within a C# program. Unsafe code must be clearly marked with the modifier unsafe, so developers cannot possibly use unsafe features accidentally. When CLR finds this unsafe modifier, the execution engine works to ensure that unsafe code cannot be executed in an untrusted environment.

Unsafe contexts
The unsafe features are available only in unsafe contexts. An unsafe context is introduced by including an unsafe modifier in the declaration.
l

A declaration of a class, struct, interface, or delegate may include an unsafe modifier, in which case the entire declaration (including the body of the class, struct, or interface) is considered an unsafe context. A declaration of a field, method, property, event, indexer, operator, constructor, destructor, or static constructor may include an unsafe modifier, in which case the entire member declaration is considered an unsafe context. An unsafe-statement enables the use of an unsafe context within a block. The entire associated block is considered an unsafe context.

In the example
public unsafe struct Node { public int Value; public Node* Left; public Node* Right; }

the unsafe modifier specified in the struct declaration causes the entire textual struct declaration to become an unsafe context. Thus, it is possible to declare the Left and Right fields to be of a pointer type. The example above could also be written

BSIT 61 Basics of .NET

101

public struct Node { public int Value; public unsafe Node* Left; public unsafe Node* Right; }

Here, the unsafe modifiers in the field declarations cause those declarations to be considered unsafe contexts. In the below example
public class A { public unsafe virtual void F() { char* p; ... } }

the unsafe modifier on the F method in A simply causes the F to become an unsafe context in which the unsafe features of the language can be used.

6.4 THREADING
Operating systems use different process space for each process, and processes receive services for operating system separately. Threads are the basic unit to which an operating system allocates processor time, and more than one thread can run inside that process. Each thread maintains exception handlers, a scheduling priority, and a set of structures which the system uses to save the thread context until it is scheduled. The thread context includes all of the information the thread needs to resume execution, including the set of CPU registers and stack, in the address space of the threads host process.

When To Use Multiple Threads


Software that requires user interaction must react to the users requests rapidly to provide a user friendly experience. At the same time, however, it must do the calculations necessary to respond to the user as fast as possible. If application uses only one thread of execution, then it may be difficult to process all the request simultaneously and decrease the data processing time of application. In such cases multiple threads can be created to do the bits of work independently to increase applications responsiveness.

Advantages of Multiple Threads


Using more than one thread, however, is the most powerful technique available to increase user

102

Chapter 6 - Advanced C#

responsiveness and process the data necessary to get the work done at almost the same time. On a computer with one processor, multiple threads can create this effect, taking advantage of the small periods of time in between users IO events to process the data in the background. For example, a user can edit a spreadsheet while another thread is recalculating other parts of the spreadsheet within the same application. Without modification, the same application would dramatically increase user satisfaction when run on a computer with more than one processor. Your single application domain could use multiple threads to accomplish the following tasks:
l l l

Communicate over a network, to a Web server and to a database. Perform operations that take a large amount of time. Distinguish tasks of varying priority. For example, a high-priority thread manages time-critical tasks, and a low-priority thread performs other tasks. Allow the user interface to remain responsive, while allocating time to background tasks.

Disadvantages of Multiple Threads


Threading also has resource requirements and potential conflicts, which should be considered when designing your application. It is good to use as few threads as possible. The resource requirements for thread are as follows:
l

Memory requirement for the context information required by processes, Application Domain objects, and threads. Therefore, the number of processes, Application Domain objects, and threads which can be created is limited by memory availability. Keeping track of a large number of threads consumes significant processor time. If there are too many threads, then there will not be any significant advantage of threads. Controlling execution of an application with many threads can be a source of many bugs and it is very complex.

Examples on Threads Usage


The example given in this section demonstrates how to create and start a thread. It shows the interaction between two threads running simultaneously within the same process. Note that we dont have to stop or free the thread. This is done automatically by the .NET Framework common language runtime. The program begins by creating an object of type A (oA) and a thread (oThread) that references the B method of the A class. The thread is then started. The IsAlive property of the thread allows the program to wait until the thread is initialized (created, allocated, and so on). The main thread is accessed through Thread, and the Sleep method tells the thread to give up its time slice and stop executing for a certain amount of milliseconds. The oThread is then stopped and joined. Joining a thread makes the main

BSIT 61 Basics of .NET

103

thread wait for it to die or for a specified time to. Finally, the program attempts to restart oThread, but fails because a thread cannot be restarted after it is stopped (aborted).
using System; using System.Threading; public class A { // This method that will be called when the thread is started public void B() { while (true) { Console.WriteLine(A.B is running in its own thread.); } } }; public class Simple { public static int Main() { Console.WriteLine(Thread Start/Stop/Join Example); A oA = new A(); // Create the thread object, passing in the A.B method // via a ThreadStart delegate. This does not start the thread. Thread oThread = new Thread(new ThreadStart(oA.B)); // Start the thread oThread.Start(); // loop until the started thread becomes alive while (!oThread.IsAlive); // Main thread sleeps for 1 ms untill oThread finishes its work Thread.Sleep(1); // oThread is stopped oThread.Abort(); // Wait until oThread finishes and Joins. oThread.Join(); Console.WriteLine(); Console.WriteLine(A.B has finished); try

104
{

Chapter 6 - Advanced C#

Console.WriteLine(Try to restart the A.B thread); oThread.Start(); } catch (ThreadStateException) { Console.Write(ThreadStateException trying to restart A.B); Console.WriteLine(Aborted threads cannot be restarted.); } return 0; } }

The Output will be


Thread Start/Stop/Join Example A.B is running in its own thread. A.B is running in its own thread. A.B is running in its own thread. ... ... A.B has finished Try to restart the A.B thread ThreadStateException trying to restart A.B Aborted threads cannot be restarted.

Pausing and Resuming Threads


After a thread has started, it can often pause thread for a fixed period of time. Calling Thread.Sleep causes the current thread to immediately block for the specified number of milliseconds, yielding the remainder of its time slice to another thread. One thread cannot call Sleep on another thread. Calling Thread.Sleep(Timeout.Infinite) causes a thread to sleep until it is interrupted by another thread that calls Thread.Interrupt or is aborted by Thread.Abort. A thread can also be paused by calling Thread.Suspend. When a thread calls Thread.Suspend on itself, the call blocks until the thread is resumed by another thread. When one thread calls Thread.Suspend on another thread, the call is a nonblocking call that causes the other thread to pause. Calling Thread.Resume breaks another thread out of the suspend state and causes the thread to resume execution, regardless of how many times Thread.Suspend was called. For example, if you call Thread.Suspend five consecutive times and then call Thread.Resume, the thread will resume execution immediately following the call to Resume. Unlike Thread.Sleep, Thread.Suspend does not cause a thread to immediately stop execution. The common language runtime must wait until the thread has reached a safe point before it can suspend the thread. A thread cannot be suspended if it has not been started or if it has stopped. The Suspend and Resume methods are not generally useful for applications. It should not be confused

BSIT 61 Basics of .NET

105

with synchronization mechanisms, because Suspend and Resume do not rely on the cooperation of the thread being controlled. They are highly intrusive and can result in serious application problems like deadlocks (for example, if you suspend a thread that holds a resource that another thread will need). Some applications do need to control the priority of threads for better performance. To do this, you should use Thread.Priority rather than Thread.Suspend. A thread can be blocked in a number of ways. For example, we can have a thread wait for another thread to stop by calling Thread.Join. We can have a thread wait for access to a synchronized object using Monitor.Wait, or we can put it to sleep using Thread.Sleep. We can interrupt a waiting thread by calling Thread.Interrupt on the blocked thread to throw a ThreadInterruptedException, which breaks the thread out of the blocking call. The thread should catch the ThreadInterruptedException and do whatever is appropriate to continue working. If the thread ignores the exception, the runtime catches the exception and stops the thread. If a thread is in wait, then Thread.Interrupt and Thread.Abort both wake the thread immediately. Thread.Interrupt wakes a thread out of any wait it might be in and causes a ThreadInterruptedException to be thrown in the destination thread. Thread.Abort is similar to Thread.Interrupt, except that it throws the ThreadAbortException. This is a special exception that cannot be caught from managed code.

Destroying Threads
The Thread.Abort method is used to stop a logical thread permanently. When we call Abort, the common language runtime throws a ThreadAbortException. The thread can catch the exception, but cannot suppress it. The runtime will execute the catch block and any finally block. Because Thread.Abort does not cause the thread to abort immediately, we must call Thread.Join to wait on the thread to be sure the thread is stopped. Join is a blocking call that does not return until the thread has actually stopped executing. Once a thread is aborted, it cannot be restarted. Thread.Join can also be called and passed a time-out period. If the thread dies before the time out has elapsed, the call returns true. Otherwise, if the time expires before the thread dies, the call returns false. Threads that are waiting on a call to Thread.Join can be interrupted by other threads that call Thread.Interrupt. A ThreadAbortException can occur anywhere in managed code. However, they only occur if a privileged thread calls Thread.Abort. The best way to handle them is to have adequate finally or catch block to maintain consistent state. The privileged code that provokes the ThreadAbortException will catch it and reset it if necessary.

106 6.5 LIBRARY BASE CLASSES

Chapter 6 - Advanced C#

The .NET Framework base classes include classes, interfaces, and value types that provide access to system functionality. To facilitate interoperability between languages, the .NET Framework base classes are CLS compliant and therefore can be used from any programming language. The .NET Framework library base classes are the foundation on which .NET applications, components, and controls are built. These also include types that perform the following functions:
l l l l l l

Represent base data types and exceptions. Encapsulate data structures. I/O operations Access information of types. .NET Framework security checks. Provide data access, GUI, and Web services.

The .NET Framework provides a rich set of interfaces, abstract and concrete (non-abstract) classes. We can use the concrete classes as is or can derive own classes from them. To use the functionality of an interface, we can either create a class that implements the interface or derive a class from one of the interface of .NET Framework classes.

Naming Conventions
.NET Framework types use a dot (.) syntax naming scheme that is in a hierarchy. This technique groups related types into namespaces so, they can be searched and referenced easily. The first part of the full name, up to the rightmost dot, is the namespace name. The last part of the full name is the type name. For example, System.Collections.ArrayList represents the ArrayList type, which belongs to the System.Collections namespace. The types in System.Collections can be used to manipulate collections of objects. The System namespace is the root namespace for fundamental types in the .NET Framework. This namespace includes classes that represent the base data types like Object (the root of the inheritance hierarchy), Byte, Char, Array, Int32, String, and so on. Many of these types correspond to the primitive data types that our programming language uses. When we write code using .NET Framework types, we can use our languages corresponding keyword when a .NET Framework base data type is expected. The following table lists some of the value types the .NET Framework supplies, briefly describes them. It indicates the corresponding type in VisualBasic.NET, C#, and the Managed C++.

BSIT 61 Basics of .NET

107
Visual Basic. C# NET Byte byte SByte sbyte No builtin type. Short short Integer int Long long UInt16 No builtin type. UInt32 No builtin type. UInt64 No builtin type. Single ushort

Class Category name Integer Byte SByte

Description An 8-bit unsigned integer. An 8-bit signed integer. Not CLS compliant.

Managed JScript C++ Char Signed char Short int ,long __int64 unsigned short unsigned int , unsigned long unsigned __int64 float double bool wchar_t byte SByte short int long UInt16

Int16 Int32 Int64 UInt16

A 16-bit signed integer. A 32-bit signed integer. A 64-bit signed integer. A 16-bit unsigned integer. Not CLS compliant. A 32-bit unsigned integer.

UInt32 Not CLS compliant. A 64-bit unsigned integer. UInt64 Not CLS compliant. Floating Single point A single-precision (32-bit) floating-point number. A double-precision (64-bit) Double floating-point number. A Boolean value (true or Boolean false). A Unicode (16-bit) Char character. Decimal A 96-bit decimal value. A signed integer whose size depends on the underlying platform (a 32-bit value on IntPtr a 32-bit platform and a 64bit value on a 64-bit platform).

uint

UInt32

ulong

UInt64

float

float double bool char Decimal

Double double Boolean bool Char char

Logical Other

Decimal decimal Decimal IntPtr IntPtr IntPtr

No built- No built- No built-in in type. in type. type.

IntPtr

108

Chapter 6 - Advanced C#

An unsigned integer whose size depends on the underlying platform (a 32- UIntPtr UIntPtr UIntPtr bit value on a 32-bit UIntPtr UIntPtr platform and a 64-bit value No built- No built- No built-in on a 64-bit platform). in type. in type. type. Not CLS compliant. The root of the object Object hierarchy. An immutable, fixed-length string of Unicode String characters.

Class objects

Object String

object string

Object* String*

Object String

Table 6.2 : .NET Framework value types

In addition to the base data types, the System namespace contains almost 100 classes, ranging from classes that handle exceptions to classes that deal with application domains and the garbage collector.

6.5.1 System.Object
System.Object class is the ultimate base class that all types directly or indirectly derive from. The object class allows us to build generic routines, provides Type System Unification, and enables working with groups collections. Commonly generic routines must accept arguments of type object and allow users to pass any type they want. This approach of generic routines is difficult to maintain because of the lack of type safety and inefficiency for value types. Generics in C# will replace the practice of using the object class for generic routines. Reference types inherit the object class either directly or through other reference types. Value types inherit implicitly from object class through System.ValueType. In C#, the object class is a language specific with the fully qualified name of System.Object. The ability of both reference types and value types to be treated as objects supports Common Type System. In many languages, built-in types such as int and float have no object-oriented properties and must be explicitly wrapped in objects to simulate object-oriented behavior. However, C# eliminates the requirement to wrap built-in types. Value types inherit from System.ValueType, which inherits from System.Object. This allows C# built-in types to be worked in a manner similar to reference types. From an object-oriented perspective, under Common Type System both reference types and value types are objects. Of course we do not get Common Type System for free. When assigning a value type to an object, in

BSIT 61 Basics of .NET

109

the background, the system performs an extra operation referred to as Boxing. After a boxing operation has completed, a value type is considered boxed. Similarly, when copying a boxed value type back to a normal value type, in the background, the system performs another operation referred to as Unboxing. While any value type can be boxed, it is not logical to assume that any reference type can be unboxed. Only objects that are previously boxed can be unboxed. When a value type is boxed, a new object for that type is created in memory and the value is copied into that object. During unboxing the value in the object is copied into the value of a value type. The below piece of code shows a simple boxing/unboxing operation.
int myValueType1 = 8; object myReferenceType = myValueType1; // myValueType is boxed int myValueType2 = (int) myReferenceType; // myValueType is unboxed

Although for performance reasons, we need to be aware of the boxing/unboxing operations. This concept makes it very simple to work with all types in the same manner for those times when such behavior in our application is necessary. The object class also facilitates using any type in a collection. It contains methods that can be reused or overridden in base types. Since collections, such as Hashtable and ArrayList accept object types, we can add any type to them. The Equals, GetType, and GetHashCode object class methods are called directly by the collection classes. Other object class methods offer general capabilities that types have access to and can expose in their interface.

The Equals Method


This is a common operation, especially for searching and sorting in collections, it tests two objects for equality. The Equals method of the object class provides a default implementation that compares two reference type objects for reference equality. Reference equality occurs when two reference type objects refer to the same object. Sometimes reference types need to define value equality instead of reference equality. Fortunately, the Equals method is virtual, so derived reference types may override it. An example is the string class, which overrides Equals to ensure that two strings are compared by the value of their strings. Value types are compared for bitwise equality. The below code demonstrates how to use the Equals method with reference types.
using System; class Employee { string e_name; public Employee(string name) { e_name = name; } }

110

Chapter 6 - Advanced C#

class EqualsDemonstration { static void Main() { EqualsDemonstration eqDemo = new EqualsDemonstration(); eqDemo.InstanceEqual(); Console.ReadLine(); } public void InstanceEqual() { string name = Joe; Employee employee1 = new Employee(name); Employee employee2 = new Employee(name); // comparing references of separate instances bool isEqual = employee1.Equals(employee2); Console.WriteLine(employee1 == employee2 - {0}, isEqual); employee2 = employee1; // comparing references of the same instance isEqual = employee1.Equals(employee2); Console.WriteLine(employee1 == employee2 - {0}, isEqual); } }

The output will be


employee1 == employee2 - False employee1 == employee2 - True

The above code shows how the default implementation of Equals in the object class performs comparison on reference types. In the InstanceEqual method the first comparison is of two separate instances of Employee, so the result of the call to Equals will be false. Next, the reference to the object that employee1 refers to is assigned to employee2, making both references refer to the same instance. This makes the next call to the Equals method return true. To change the way Equals works, the Employee class could override Equals and provide an implementation based on equality of the e_name member. There is also a static Equals method that performs the same task: Object.Equals(object obj1, object obj2).

The ReferenceEquals Method


In the object class, the Equals and ReferenceEquals methods are semantically equivalent, except

BSIT 61 Basics of .NET

111

that the ReferenceEquals works only on object instances. The ReferenceEquals method is static. The below program demonstrates how to use the ReferenceEquals method.
using System; class Employee { string e_name; public Employee(string name) { e_name = name; } } class ReferenceEqualsDemo { static void Main() { ReferenceEqualsDemo refEqDem = new ReferenceEqualsDemo(); refEqDem.InstanceEqual(); Console.ReadLine(); } public void InstanceEqual() { string name = Joe; Employee employee1 = new Employee(name); Employee employee2 = new Employee(name); // comparing separate instances bool isEqual = Object.ReferenceEquals(employee1, employee2); Console.WriteLine(employee1 == employee2 - {0}, isEqual); employee2 = employee1; // comparing the same instance isEqual = Object.ReferenceEquals(employee1, employee2); Console.WriteLine(employee1 == employee2 - {0}, isEqual); } }

The output will be


employee1 == employee2 - False employee1 == employee2 - True

112

Chapter 6 - Advanced C#

Notice that the previous both code are the same except that second one uses the ReferenceEquals method. The results are also the same.

The ToString Method


The purpose of the ToString method is to return a string representation of a type. The default implementation in the object class returns a string with the name of the object. The below given piece of code demonstrates how to implement the ToString method in our own type.
using System; class Employee { string e_name; public Employee(string name) { e_name = name; } // If ToString() is not overridden, the output of this program will be Employee. public override string ToString() { return String.Format([Employee: {0}], e_name); } } class ToStringDemonstration { static void Main() { Employee emp = new Employee(Joe); Console.WriteLine(emp.ToString()); Console.ReadLine(); } }

The output will be


[Employee: Joe]

The ToString method overrides ToString in the object class. We can use ToString to facilitate debugging by providing human readable information about our type that can be viewed by developers inspecting program output emitted by calls to the ToString method.

The GetType Method


GetType is the basis for using reflection in .NET. It returns a Type object, describing the object it was

BSIT 61 Basics of .NET

113

called on. It can then be used to extract type member data like methods and fields that may subsequently be used for late-bound method invocations. The GetType method is also useful if we get an object at runtime and we do not know what its type is. We can use the returned Type object to figure out what to do with the object. Below listed code demonstrates how to use the GetType method.
using System; class Employee { } class GetTypeDemonstration { static void Main() { object emp1 = new Employee(); Employee emp2 = new Employee(); Console.WriteLine(emp1.GetType()); Console.WriteLine(emp2.GetType()); Console.ReadLine(); } }

The output will be


Employee Employee

There are two instances of the Employee class created in the Main method. The first is assigned to a reference of type object and the second is assigned to a reference of type Employee. When we run, the program will print Employee as the result of the call to GetType. This shows that GetType returns the run-time type of the object it is called on, rather than the compile-time reference it is assigned to.

The GetHashCode Method


The GetHashCode method makes any object usable in a Hashtable or any hashing algorithm. Since the default algorithm supplied by the GetHashCode method of the object class is not guaranteed to be unique, we should override GetHashCode in our custom types. Below listing demonstrates how to implement a custom GetHashCode method.
using System; class Employee { string e_name; public Employee(string name) {

114
e_name = name; } public override int GetHashCode() { string uniqueString = ToString(); return uniqueString.GetHashCode(); }

Chapter 6 - Advanced C#

public override string ToString() { return String.Format([Employee: {0}], e_name); } } class GetHashCodeDemonstration { static void Main() { Employee emp = new Employee(Joe); Console.WriteLine(emp.GetHashCode()); Console.ReadLine(); } }

The output will be


-275241189

The Employee class overrides the GetHashCode method to provide a unique number for each unique instance of the Employee class. This is accomplished by using the ToString method that will return a string uniquely representing the value of this instance. Then GetHashCode is called on the string and returned to the caller. The benefits of using the string class are that it already has a GetHashCode function that can be used. The GetHashCode method of the string class returns a random distribution of hash codes, guarantees codes are unique for different strings, and ensures codes are identical for the same strings.

The MemberwiseClone Method


Whenever we need to create a bitwise copy (shallow copy) of our type, the MemberwiseClone method is used. As such, if we perform a MemberwiseClone on our class, it will make a copy of the type and all contained value types and references types. However, it will not copy the objects that the reference type members in our type refer to. This behavior of only making a copy of the first level of our type tells

BSIT 61 Basics of .NET

115

the reason why a MemberwiseClone is called a shallow copy. Since the MemberwiseClone method is not virtual, we can not override it in derived classes. Program below shows how to use MemberwiseClone.
using System; public class Address { } class Employee { Address e_address = new Address(); string e_name; public Employee(string name) { e_name = name; } public Employee ShallowCopy() { return (Employee)MemberwiseClone(); } public Address EmployeeAddress { get { return e_address; } } } class MemberwiseCloneDemonstration { static void Main() { Employee emp1 = new Employee(Joe); Employee emp2 = emp1.ShallowCopy(); // compare Employee references bool isEqual = Object.ReferenceEquals(emp1, emp2); Console.WriteLine(emp1 == emp2 - {0}, isEqual); //compare reference of Address object in each Employee object isEqual = Object.ReferenceEquals(emp1.EmployeeAddress, emp2.EmployeeAddress); Console.WriteLine(emp1.EmployeeAddress == emp2.EmployeeAddress {0}, isEqual); Console.ReadLine(); } }

116
The output will be
emp1 == emp2 - False emp1.EmployeeAddress == emp2.EmployeeAddress True

Chapter 6 - Advanced C#

Since MemberwiseClone has protected visibility, wraps the call to it in the ShallowCopy method of the Employee class. When the Main method calls ShallowCopy, the emp2 variable holds a reference to a copy of emp1. However, this is a shallow copy, as subsequent statements prove. The first call to ReferenceEquals shows that the emp1 and emp2 variables refer to separate instances. The second call to ReferenceEquals performs a comparison on the Address object within the emp1 and emp2 instances. The comparison demonstrates that both of the Address references point to the same object, proving that only a shallow copy has been performed.

The Finalize Method


Although the object class has a Finalize method, it is not available to C# programs in that form. Instead, we can use what is called a destructor in C#, which is synonymous with the Finalize method. In further discussion, we will refer to the Finalize method as a destructor. The original purpose of the destructor was to serve as a place where we can release unmanaged resources such as network connections, operating system resources, or file streams. However, in practice we never want to use the destructor. The reason is that a destructor is executed automatically by the garbage collector. Developers familiar with C++ will notice that this is a distinct difference in destructor behavior because in C++ a destructor is executed deterministically, as soon as an object is freed. The solution to this problem in C# is to implement the IDisposable interface on all our types that need to release unmanaged resources. Below program shows a class that implements a destructor.
using System; class Employee { string e_name; public Employee(string name) { e_name = name; Console.WriteLine(Employee Name: {0}, e_name); } ~Employee() { Console.WriteLine(Employee destructor executed.); } } class DestructorDemonstration { static void Main()

BSIT 61 Basics of .NET

117

{ Employee emp = new Employee(Joe); } }

The output will be


Employee Name: Joe Employee destructor executed.

The Employee class implements a destructor. Destructors are prefixed with a () tilde and named the same as their containing class. Additionally, they do not have parameters. Value types do not have destructors. If we run this program it will print employees name to the console and then executes the destructor. Since it is so small, it will not consume enough memory resources to force a garbage collection, which in turn would call the destructor. If the program was holding an unmanaged resource, the unmanaged resource would not be released. When employees name is printed to the console, the CLR will initiate a garbage collection and the program will print Employee destructor executed. to the screen when the garbage collector calls the destructor, prior to final program shutdown.

6.5.2 String Handling


In C#, a text string is stored in a data type named string, which is an alias to the System.String type. In other words, when we create a string, we instantiate a System.String object. In addition to its instance members, the System.String class has quite a few important static methods. These methods do not require a string instance to work. It is important to understand that the string type is immutable. This means that once it has been created, a string cannot be changed. No characters can be added or removed from it, nor can its length be changed. But let us have a look at below piece of code
string str = I am going to have a lot of fun; str += with Dudley this summer. ... ; str += The End;

Well, here set of statements actually create a new instance of the variable str each time a value is assigned to str. In other words, in this example, an instance of str has been created, and a literal string value assigned to it three times. The statement that the type is immutable means that an instance cannot be edited but it can be assigned.

118

Chapter 6 - Advanced C#

Using an instance method without an assignment is syntactically legal, but it does not do anything i.e., it has no effect. For example
string str = hello; str.Replace (l, L); // Does not do anything

does not change the contents of the variable str, although combining it with an assignment would work:
string str = hello; str = str.Replace (l, L);

Now the new value of str is, of course, heLLo. It is easy enough to use assignments when we need to change the value of string. But instantiating and destroying strings every time will result in negative performance consequences. If performance is an issue, we should consider working with instances of the System.Text.StringBuilder class, which are mutable (can be changed). Once created, a string has a specific length, which is fixed. A C# string is not a terminated array of characters (unlike in the C language, in which a string is simply an array of characters terminated with a zero byte). So, how does one determine the length of a C# string? The length of C# string can be known by querying the read-only Length property of the string instance. For example Len = str.Length; gives the length of string str.

6.5.3 Arrays
An array is a data structure that contains a number of variables called the elements of the array. The array elements are accessed through indexes. C# arrays are zero indexed; that is, the array indexes start at zero. All of the array elements must be of the same type. Array elements can be of any type, including an array type. An array can be a single-dimensional array, or a multidimensional array. Array types are reference types derived from the abstract base type System.Array. We will discuss the following topics one by one
l l l l

Single-Dimensional Arrays Multidimensional Arrays Jagged Arrays Passing Arrays Using ref and out

BSIT 61 Basics of .NET

119

6.5.3.1 Single-Dimensional Arrays


We can declare an array of five integers as in the following example:
int[] myArray = new int [5];

This array contains the elements from myArray[0] to myArray[4]. The new operator is used to create the array and initialize the array elements to their default values. In this case, all the array elements are initialized to zero. An array that stores string elements can be declared in the same way. For example:
string[] myStringArray = new string[6];

Array Initialization
It is possible to initialize an array upon declaration. The number of elements of the array is not needed to be specified because it is already supplied by the number of elements in the initialization list. For example:
int[] myArray = new int[] {1, 3, 5, 7, 9};

A string array can be initialized in the same way. The following is a declaration of a string array where each array element is initialized by a name of a day.
string[] weekDays = new string[] {Sun,Sat,Mon,Tue,Wed,Thu,Fri};

When we initialize an array upon declaration, it is possible to use the following shortcuts:
int[] myArray = {1, 3, 5, 7, 9}; string[] weekDays = {Sun,Sat,Mon,Tue,Wed,Thu,Fri};

It is possible to declare an array variable without initialization, but we must use the new operator when we assign an array to this variable. For example:
int[] myArray; myArray = new int[] {1, 3, 5, 7, 9}; myArray = {1, 3, 5, 7, 9}; // Error // OK

Value Type and Reference Type Arrays Consider the following array declaration:
MyType[] myArray = new MyType[10];

120

Chapter 6 - Advanced C#

The result of this statement depends on whether MyType is a value type or a reference type. If it is a value type, the statement results in creating an array of 10 instances of the type MyType. If MyType is a reference type, the statement creates an array of 10 elements, each of which is initialized to a null reference.

Passing Arrays as Parameters


We can pass an initialized array to a method. For example:
PrintArray(myArray);

We can also initialize and pass a new array in one step. For example:
PrintArray(new int[] {1, 3, 5, 7, 9});

In the following example, a string array is initialized and passed as a parameter to the PrintArray method, where its elements are displayed:
using System; public class ArrayClass { static void PrintArray(string[] s) { for (int i = 0 ; i < s.Length ; i++) Console.Write(s[i] + {0}, i < s.Length - 1 ? : ); Console.WriteLine(); } public static void Main() { // Declare and initialize an array: string[] WeekDays = new string [] {Sun,Sat,Mon,Tue,Wed,Thu,Fri}; // Pass the array as a parameter: PrintArray(WeekDays); } }

The output will be


Sun Sat Mon Tue Wed Thu Fri

BSIT 61 Basics of .NET

121

6.5.3.2 Multidimensional Arrays


Arrays can have more than one dimension. For example, the following declaration creates a twodimensional array of four rows and two columns:
int[,] myArray = new int[4,2];

Also it can create an array of three dimensions, 4, 2, and 3, as show below:


int[,,] myArray = new int [4,2,3];

Array Initialization
We can initialize the array upon declaration as shown in the following example:
int[,] myArray = new int[,] {{1,2}, {3,4}, {5,6}, {7,8}};

We can also initialize the array without specifying the rank (number of elements):
int[,] myArray = {{1,2}, {3,4}, {5,6}, {7,8}};

If we choose to declare an array variable without initialization, we must use the new operator to assign an array to the variable. For example:
int[,] myArray; myArray = new int[,] {{1,2}, {3,4}, {5,6}, {7,8}}; myArray = {{1,2}, {3,4}, {5,6}, {7,8}}; // Error // OK

We can also assign a value to an array element, for example:


myArray[2,1] = 25;

Passing Arrays as Parameters


We can pass an initialized array to a method. For example:
PrintArray(myArray);

we can also initialize and pass a new array in one step. For example:
PrintArray(new int[,] {{1,2}, {3,4}, {5,6}, {7,8}});

In this example, a two-dimensional array is initialized and passed to the PrintArray method, where its elements are displayed.

122

Chapter 6 - Advanced C#

using System; public class ArrayClass { static void PrintArray(int[,] s) { // Display the array elements: for (int i=0; i < 4; i++) for (int j=0; j < 2; j++) Console.WriteLine(Element({0},{1})={2},i,j,s[i,j]); } public static void Main() { // Pass the array as a parameter: PrintArray(new int[,] {{1,2}, {3,4}, {5,6}, {7,8}}); } }

The output will be


Element(0,0)=1 Element(0,1)=2 Element(1,0)=3 Element(1,1)=4 Element(2,0)=5 Element(2,1)=6 Element(3,0)=7 Element(3,1)=8

6.5.3.3 Jagged Arrays


A jagged array is an array whose elements are arrays. The elements of a jagged array can be of different dimensions and sizes. A jagged array is sometimes called an array-of-arrays. This we will see examples of declaring, initializing, and accessing jagged arrays. The following is a declaration of a single-dimensional array that has three elements, each of which is a single-dimensional array of integers:
int[][] myJaggedArray = new int[3][];

Before we can use myJaggedArray, its elements must be initialized. We can initialize the elements like:

myJaggedArray[0] = new int[5]; myJaggedArray[1] = new int[4]; myJaggedArray[2] = new int[2];

BSIT 61 Basics of .NET

123

Each of the elements is a single-dimensional array of integers. The first element is an array of 5 integers, the second is an array of 4 integers, and the third is an array of 2 integers. It is also possible to use initializers to fill the array elements with values, in which case we do not need the array size, for example:
myJaggedArray[0] = new int[] {1,3,5,7,9}; myJaggedArray[1] = new int[] {0,2,4,6}; myJaggedArray[2] = new int[] {11,22};

We can also initialize the array upon declaration like this:


int[][] myJaggedArray = new int [][] { new int[] {1,3,5,7,9}, new int[] {0,2,4,6}, new int[] {11,22} };

We can use the following shortcut. Notice that we cannot omit the new operator from the elements initialization because there is no default initialization for the elements.
int[][] myJaggedArray = { new int[] {1,3,5,7,9}, new int[] {0,2,4,6}, new int[] {11,22} };

We can access individual array elements like these examples:


// Assign 33 to the second element of the first array: myJaggedArray[0][1] = 33; // Assign 44 to the second element of the third array: myJaggedArray[2][1] = 44;

It is possible to mix jagged and multidimensional arrays. The following is a declaration and initialization of a single-dimensional jagged array that contains two-dimensional array elements of different sizes:
int[][,] myJaggedArray = new int [3][,] { new int[,] { {1,3}, {5,7} }, new int[,] { {0,2}, {4,6}, {8,10} }, new int[,] { {11,22}, {99,88}, {0,9} } };

We can access individual elements like this example, which displays the value of the element [1,0] of the first array (value 5):

124
Console.Write({0}, myJaggedArray[0][1,0]);

Chapter 6 - Advanced C#

This example builds an array, myArray, whose elements are arrays. Each one of the array elements has a different size.
using System; public class JaggedArrayDemonstration { public static void Main() { // Declare the Jagged array of two elements: int[][] myArray = new int[2][]; // Initialize the elements: myArray[0] = new int[5] {1,3,5,7,9}; myArray[1] = new int[4] {2,4,6,8}; // Display the array elements: for (int i=0; i < myArray.Length; i++) { Console.Write(Element({0}): , i); for (int j = 0 ; j < myArray[i].Length ; j++) Console.Write({0}{1}, myArray[i][j], j == (myArray[i].Length-1) ? : ); Console.WriteLine(); } } }

The output will be

Element(0): 1 3 5 7 9 Element(1): 2 4 6 8

6.5.3.4 Passing Arrays Using ref and out


Like all out parameters, an out parameter of an array type must be assigned before it is used; that is, it must be assigned by the callee. For example:

BSIT 61 Basics of .NET

125

public static void MyMethod(out int[] arr) { arr = new int[10]; // definite assignment of arr }

Like all ref parameters, a ref parameter of an array type must be definitely assigned by the caller. Therefore, there is no need to be definitely assigned by the callee. A ref parameter of an array type may be altered as a result of the call. For example, the array can be assigned the null value or can be initialized to a different array. For example:
public static void MyMethod(ref int[] arr) { arr = new int[10]; // arr initialized to a different array }

The following two examples demonstrate the difference between out and ref when used in passing arrays to methods.

Example 1
In this example, the array myArray is declared in the caller (the Main method), and initialized in the FillArray method. Then, the array elements are returned to the caller and displayed.
using System; class TestOut { static public void FillArray(out int[] myArray) { // Initialize the array: myArray = new int[5] {1, 2, 3, 4, 5}; } static public void Main() { int[] myArray; // Initialization is not required // Pass the array to the callee using out: FillArray(out myArray); // Display the array elements: Console.WriteLine(Array elements are:); for (int i=0; i < myArray.Length; i++) Console.WriteLine(myArray[i]); } }

126
The output will be
Array elements are: 1 2 3 4 5

Chapter 6 - Advanced C#

Example 2
In this example, the array myArray is initialized in the caller (the Main method), and passed to the FillArray method by using the ref parameter. Some of the array elements are updated in the FillArray method. Then, the array elements are returned to the caller and displayed.
using System; class TestRef { public static void FillArray(ref int[] arr) { // Create the array if (arr == null) arr = new int[10]; // Otherwise fill the array: arr[0] = 123; arr[4] = 1024; } static public void Main () { // Initialize the array: int[] myArray = {1,2,3,4,5}; // Pass the array using ref: FillArray(ref myArray); // Display the updated array: Console.WriteLine(Array elements are:); for (int i = 0; i < myArray.Length; i++) Console.WriteLine(myArray[i]); } }

The output will be

BSIT 61 Basics of .NET

127

Array elements are: 123 2 3 4 1024

6.5.4 System.Collections
The System.Collections namespace contains interfaces and classes that define various collections of objects, such as lists, queues, bit arrays, hashtables and dictionaries. Each class has a set of methods and properties, which are used on those corresponding class objects.

Class ArrayList BitArray CaseInsensitiveComparer CaseInsensitiveHashCodeProvider CollectionBase Comparer DictionaryBase Hashtable Queue ReadOnlyCollectionBase SortedList Stack

Description The IList interface (to implement list) is used, in which an array whose size is dynamically increased as required. Manages a compact array of bit values, which are represented as Booleans. Compares two objects for equivalence. The case of the string is ignored while comparing. Supplies a hash code for an object, using a hashing algorithm. The case of the string is ignored. Provides the abstract base class for a strongly typed collection. Compares two objects for equivalence, where string comparisons are case-sensitive. Provides the abstract base class for a strongly typed collection of key-and-value pairs. Represents a collection of key-and-value pairs that are organized based on the hash code of the key. Represents a FIFO collection of objects. Provides the abstract base class for a strongly typed read-only collection. Represents a collection of key-and-value pairs that are sorted by the keys and are accessible by key and by index. Represents a simple LIFO collection of objects.

Table 6.4 : Lists the important classes of System.Collection

128
SUMMARY

Chapter 6 - Advanced C#

C# compiler does not have a separate preprocessor; the directives are processed as if there was a preprocessor. These directives are used during conditional compilation. In the .NET Framework exception handling, an exception object that inherits from the ExceptionClass class is thrown from an area of code where an exception has occurred, the thrown exception is caught to avoid abnormal application program termination. Unsafe code allows declaring and operating on pointers, to perform conversions between pointers and integral types, to take the address of variables, and so forth. Threading is supported by C# through the use of System.Threading. This class provides built-in features to support threading. The .NET Framework library base classes are the foundation on which .NET applications, components, and controls are built. The .NET Framework base classes include classes, interfaces, and value types that provide access to system functionality. To facilitate interoperability between languages, the .NET Framework base classes are CLS compliant and therefore can be used from any programming language. System.Object class is the ultimate base class that all types directly or indirectly derive from. In C#, a text string is stored in a data type named string, which is an alias to the System.String type. Array types are reference types derived from the abstract base type System.Array. The System.Collections namespace contains interfaces and classes that define various collections of objects, such as lists, queues, bit arrays, hashtables and dictionaries.

QUESTIONS
1. What is a preprocessor? What does the #if, #else, #elif, #endif, #define, #undef, #warning, #error, and #line directives do? Give examples for each. 2. 3. 4. 5. 6. 7. 8. 9. What is an exception? How exceptions are handled in C#? What is an unsafe code? Explain. What is threading? List out the advantages and disadvantages of multiple threads. Write a note in Library Base Classes. What is the role of System.Object, System.String, System.Array and System.Collections Classes? What are the different methods supported by System.Object class? Give an example for each. What is boxing and unboxing? Explain with an example. Write a program to replace all r by R in the string rose is a rose.

10. Write a note on a. Single-Dimensional Arrays

BSIT 61 Basics of .NET

129

b. c. d. 11.

Multidimensional Arrays Jagged Arrays Passing Arrays Using ref and out

What is the use of System.Collections class?

130
Chapter 7

Chapter 7 - Programming with Ado.NET

Programming with ADO.NET

By the end of this chapter, you will 8 8 8 Have an ADO.NET working concept and its architecture Learn how to use DataSet and DataProvider See an ADO.NET implementation with example

7.1 ADO.NET OVERVIEW


ActiveX Data Objects for the .NET Framework (ADO.NET) is a set of classes that provide data access services to the .NET programmer. ADO.NET provides a rich set of components for creating distributed, data-sharing applications. It is an integral part of the .NET Framework, providing access to relational database, XML, and application data. ADO.NET supports a variety of development needs, including the creation of front end database clients and middle tier business objects used by applications, tools, languages, or Internet browsers. ADO.NET provides consistent access to data sources such as Microsoft SQL Server, or data sources exposed via OLE DB and XML. Data sharing applications can use ADO.NET to connect to these data sources and retrieve, manipulate, and update data. ADO.NET includes .NET data providers or data adapters for connecting to a database, executing commands, and retrieving results. Those results are either processed directly, or placed in an ADO.NET

130

Chapter 7 - Programming with Ado.NET

BSIT 61 Basics of .NET

131

DataSet object in order for further processing. The ADO.NET DataSet object can also be used to manage data local to the application. ADO.NET is a kind of an abstraction layer, as shown in the figure 1.8. It lets us deal with some .NET classes that simplify the whole issue of connecting to databases. In this section, we will try to get a big picture about ADO.NET. If we get oriented correctly, we can understand all the pieces and how they fit together. Let us consider a problem to understand the underlying concept. We has a database somewhere and It is connected to a SQL server. Now We need to build a form, and display some data from that database on the form. We will also use the User Interface widget called a datagrid to display data out of a relational database. The problem considered until now can be represented in the below figure 7.1.
SQL Server

Form

SQL Database

DataGrid

Figure 7.1 : Disconnected model with database server at one end and DataGrid control at the other end

We have a disconnected model. Now we will design our program using .NET ADO concept to implement the above problem. We require a dataset. Dataset is a place where we are going to retrieve data from the server and put it into the dataset. So now our above figure 7.1 will be something like below figure 7.2.
SQL Server DataSet

SQL Database Form

DataGrid

Figure 7.2 : Disconnected model with database server at one end. DataGrid control and DataSet at the other end

132

Chapter 7 - Programming with Ado.NET

We will now going to use data binding to connect the datagrid automatically to the dataset, as shown in figure 7.3 below. When the dataset changes, the datagrid will show it. If the datagrid changes, it will be pushed down into the dataset.
SQL Server DataSet

SQL Database Form

DataGrid

Figure 7.3 : DataGrid control is bound to DataSet

We still have not bridge the gap from the SQL database to the dataset. To do that we have the magic component class called a data adapter. A data adapter sits between that dataset and the SQL server, as shown below. So now we have got a picture, but we still have to see, what goes on inside a data adapter and how we wire it up.
SQL Server Data Adapter SQL Command Select * from Table1 SQL Connection data source = myComputer, Fill( myDataSet, myTable );

DataSet SQL Database

Form

DataGrid

Figure 7.4 : Model is now connected by using Data Adapter

BSIT 61 Basics of .NET

133

The data adapter needs a SQL commands. These SQL command select rows out of the table that we are interested in. In .NET we have an object of type SQL Command. It has a couple of properties that we need to set, and then we can use it, the data adapter can use it to interrogate the database. Knowing a SQL command isnt enough, there might be a lot of databases with a lot of tables. We are selecting data from Table 1, but do not know where Table 1 is located in all these databases. For a SQL command to execute, we have to use another .NET class called a SQL connection. So, What is a SQL connection? Well, SQL connection has connection string and some other little property, that has to be set. The connection string specifies things like, what machine is this database on, is there a password that is needed, what kind of security is involved with accessing this database? All these things can be set with the string inside the SQL connection. Now, We have got our data grid connected to our dataset, we have instantiated a data adapter, we have a SQL command to select data. The data adapter has a method called Fill. What Fill does is, it use the Select command to go extract data from the database. It creates a table inside the dataset. It puts those retrieved rows inside that table of dataset, and it gives whatever name we want. So we have called it Table1. Once that data is in the dataset, it doesnt matter where it came from, whether it was a SQL database, an XML database, etc. So now the picture is clear, datagrid is bound to dataset with a data adapter sitting between it and the database. We need a SQL command and a SQL connection, and then the program is ready to work.

7.2 ADO.NET ARCHITECTURE


Data processing has traditionally relied primarily on a connection based, two tier model. As data processing increasingly uses multi-tier architectures, programmers are switching to a disconnected approach to provide better scalability for their applications.

XML and ADO.NET


ADO.NET leverages the power of XML to provide disconnected access to data. ADO.NET was designed hand-in-hand with the XML classes in the .NET Framework. Both are components of a single architecture. ADO.NET and the XML classes in the .NET Framework converge in the DataSet object. The DataSet can be populated with data from an XML source (file or an XML stream). The native serialization format of the DataSet is XML, it is an excellent medium for moving data between tiers making the DataSet an optimal choice for remoting data and schema context to and from an XML Web service.

134
ADO.NET Components

Chapter 7 - Programming with Ado.NET

The ADO.NET components have been designed for easy data access and data manipulation. There are two central components of ADO.NET - the DataSet, and the .NET data provider. The .NET data provider is a set of components including the Connection, Command, DataReader, and DataAdapter objects. The ADO.NET DataSet is the core component of the disconnected architecture of ADO.NET. The DataSet is explicitly designed for data access independent of any data source. It can be used with multiple and different data sources, used with XML data, or used to manage data local to the application. The DataSet contains a collection of one or more DataTable objects are made up of rows and columns of data, as well as primary key, foreign key, constraint, and relation information about the data. The other core element of the ADO.NET architecture is the .NET data provider, whose components (Connection, Command, DataReader, and DataAdapter) are explicitly designed for data manipulation and forward-only, read-only access to data. The Connection object provides connectivity to a data source. The Command object enables access to database commands to return data, modify data, run stored procedures, etc. The DataReader provides a high-performance stream of data from the data source. Finally, the DataAdapter provides the bridge between the DataSet object and the data source. The DataAdapter uses Command objects to execute SQL commands at the data source to both load the DataSet with data, and to update changes made to the data in the DataSet back to the data source. The following diagram illustrates the components of ADO.NET architecture.

Figure 7.5 : Components of ADO.NET Architecture

BSIT 61 Basics of .NET

135

Choosing a DataSet and a DataReader


When deciding whether our application should use a DataSet or DataReader, we should consider the type of functionality that our application requires. We should use a DataSet to do the following:
l l

Remote data between tiers or from an XML Web service. Interact with data dynamically such as binding data to Forms control or combining and relating data from multiple sources. Cache data locally in our application. Provide a hierarchical XML view of relational data. Perform extensive processing on data without requiring an open connection to the data source.

l l l

If we do not require the functionality provided by the DataSet, we can improve the performance using the DataReader. Although the DataAdapter uses the DataReader to fill the contents of a DataSet, by using the DataReader we can receive performance gains because we will save memory that will be consumed by the DataSet, and also saving the processing required creating and filling the contents of the DataSet.

7.3 DATA PROVIDER


A .NET data provider is used for connecting to a database, executing commands, and retrieving results. Those results are either processed directly, or placed in an ADO.NET DataSet. The .NET data provider is designed to be lightweight, creating a minimal layer between the data source and application code, increasing performance without sacrificing functionality. The following table outlines the four core components of .NET data provider.

Object Connection Command DataReader DataAdapter

Description Establishes a connection to a specified data source. Executes a command against a data source. Reads a forward-only, read-only stream of data from a data source. Populates a DataSet and resolves updates with the data source.

Table 7.1 : Components of .NET Data Provider

136 7.4 DATA SET

Chapter 7 - Programming with Ado.NET

The DataSet object is central to supporting disconnected, distributed data scenarios with ADO.NET. The DataSet is a memory resident representation of data that provides a consistent relational programming model regardless of the data source. The following illustration shows the DataSet object model.

DataSet object model


The methods and objects in a DataSet are consistent with those in the relational database model.

DataSet
9 9 9

DataRelationCollection ExtendedProperties DataTableCollection


9 9

DataTable DataRowCollection
9

DataRow

9 9 9 9 9

DataView ChildRelations ParentRelations Constraints DataColumnCollection


9

DataColumn
9

ExtentedProperties

9 9

ExtendedProperties PrimaryKey

Figure 7.6 : Hierarchical diagram showing DataSet Class hierarchy

The DataTableCollection
An ADO.NET DataSet contains a collection of zero or more tables represented by DataTable objects. The DataTableCollection contains all the DataTable objects in a DataSet. A DataTable is defined in the System.Data namespace and it represents a single table of data. It contains a collection of columns represented by a DataColumnCollection, and constraints represented by a ConstraintCollection, which together define the table schema. A DataTable also contains a collection of rows represented by the DataRowCollection, a DataRow retains both its new and old changes to the values stored in the row.

BSIT 61 Basics of .NET

137

The DataRelationCollection
A DataSet contains all its relationships stored in its DataRelationCollection object. A relationship is represented by the DataRelation object, which associates rows in one DataTable with rows in another DataTable. It is something like a join path that might exist between primary and foreign key columns in a relational database. A DataRelation identifies matching columns in two tables of a DataSet. Relationships enable navigation from one table to another within a DataSet. The essential elements of a DataRelation are the name of the relationship, the name of the tables being related, and the related columns in each table. Relationships can be built with more than one column per table by specifying an array of DataColumn objects as the key columns. When a relationship is added to the DataRelationCollection, it may optionally add a UniqueKeyConstraint and a ForeignKeyConstraint to enforce integrity constraints when changes are made to related column values.

ExtendedProperties
The DataSet has an ExtendedProperties property. ExtendedProperties is a PropertyCollection where we can place information, such as the SELECT statement that was used to generate the resultset, or a date/time stamp of when the data was generated

7.5 SAMPLE IMPLEMENTATION USING ADO.NET


This section demonstrates the basic database operations using the ADO.NET classes. The sample code in this chapter uses the OleDb Provider. Here is some sample code to execute a simple query.
string connectionString = Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Samples\\Employee.mdb; OleDbConnection myConnection = new OleDbConnection( ConnectionString ); myConnection.Open(); string query = insert into EMPLOYEE_TABLE (EmployeeID, Name, Address) VALUES (101, John, 3960 CliffValley Way); OleDbCommand myCommand = new OleDbCommand(); myCommand.CommandText = query; myCommand.Connection = myConnection; myCommand.ExecuteNonQuery(); myConnection.Close();

Let us analyze the above code. First we have declared a connection string. The connection string points to an MS Access database (Employee.mdb).

138

Chapter 7 - Programming with Ado.NET

In the next step, we are creating an OleDbConnection object and passing the connection string to this object. The line myConnection.Open(); in the above code will open a connection to the MS Access database specified in the connection string. If the database does not exists or if it is not able to open a connection for some other reason, the .Open call will fail. Next step is, creating an OleDbCommand object. This command object is used to execute SQL statements and uses the connection opened by the OleDbConnection object. Note that before executing a command, we have to establish a valid connection to the database. And finally, after we have executed with the command, we will close the connection. The above code executes a SQL statement and returns no data from database. We are calling the method ExecuteNonQuery() on the command object. If we have a select ... statement which returns data from database, we cannot use the ExecuteNonQuery() method. The following sample demonstrates using OleDbDataAdapter Object and DataSet to retrieve data from databbase.
string connectionString = Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Samples\\Employee.mdb; OleDbConnection myConnection = new OleDbConnection( connectionString ); string query = select * from EMPLOYEE_TABLE; OleDbDataAdapter myAdapter = new OleDbDataAdapter( query, myConnection ); DataSet employeeData = new DataSet(); myAdapter.Fill ( employeeData );

Here in the above piece of code, we are creating an OleDbConnection object and we are just passing the object to the OleDbDataAdapter object. Also, we pass the select ... query to the OleDbDataAdapter. Next, we call the .Fill() method of the OleDbDataAdapter. This step will populate the dataset ( called employeeData ) with the data retrieved for the SQL statement select * from EMPLOYEE As you already know, a DataSet can contain a collection of tables. But in our case, our SQL statement will retrieve data from only one table. So, our DataSet will have only one table We can also iterate through the table in the dataset and retrieve all the records. See the following code demonstrating it:
string connectionString = Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Samples\\Employee.mdb; OleDbConnection myConnection = new OleDbConnection( connectionString );

BSIT 61 Basics of .NET

139

string query = select * from EMPLOYEE_TABLE; OleDbDataAdapter myAdapter = new OleDbDataAdapter( query, myConnection ); DataSet employeeData = new DataSet(); myAdapter.Fill( employeeData ); // Repeat for each table in the DataSet collection. foreach ( DataTable table in employeeData.Tables ) { // Repeat for each row in the table. foreach ( DataRow row in table.Rows ) { MessageBox.Show(Employee Number : + row[EmployeeNumber].ToString()); MessageBox.Show( Name : + row[Name].ToString() ); MessageBox.Show( Address : + row[Address].ToString() ); } }

The above code retrieves all the records from the employee table and displays all the fields.

SUMMARY
ADO.NET includes .NET data providers or data adapters for connecting to a database, executing commands, and retrieving results. In ADO.NET data source is bound to dataset with a data adapter sitting between it and the database. ADO.NET leverages the power of XML to provide disconnected access to data. ADO.NET was designed hand-in-hand with the XML classes in the .NET Framework. A .NET data provider is used for connecting to a database, executing commands, and retrieving results. Those results are either processed directly, or placed in an ADO.NET DataSet.

QUESTIONS
1. 2. 3. 4. 5. Give the overall concept of ADO.NET with the help of figures. (Hint: Big picture) Explain in detail ADO.NET architecture. What is a data provider? Explain. What is a data set? Explain Write a program to show the demonstration of ADO.NET.

140
Chapter 8

Chapter 8 - Internet Programming

Internet Programming

By the end of this chapter, you will have 8 8 8 An brief overview about internet programming in .NET framework Learn how web services and web forms work Learn briefly ASP.NET

In this chapter we will explore the .NET framework support for Internet-based programming. We are going to cover several topics under this Chapter. Firstly we will understand XML Web services, and next we will take Web Forms, which are browser-based Web applications. ASP.NET, is also a important topic to understand in internet programming.

8.1 WEB SERVICES


We will try to a big picture of what is this web service is? A Web service is a very simple idea. It is a application logic, accessible through some standard Web protocol. At this point, a diagram will help us to get a big picture. The figure 8.1 below has a consumer of a service on one side and a Web service on another side.

140

Chapter 8 - Internet Programming

BSIT 61 Basics of .NET

141

Request Consumer Application

Web Service

Response XML

Web service is collection of methods that can be called from remote locations

Figure 8.1 : Request and Response process between application and web services

The consumer shots a request to the Web service. Web service or XML web service is just a collection of methods that can be called from some other computer, from a remote location. The cloud in the middle of figure is the Internet. The result goes back to the consumer. To the consumer there is very little difference from calling a method that is running on the same machine, but it is running at some other location on the Internet. Why do we call it XML Web services and why do we have that XML label in the above figure? Well, XML is the tool that is used automatically to serialize the request and sent it using HTTP across the Internet to the Web service, if we are developing code in the .NET Framework. The Web service calculates the result, and that result is serialized into XML to get sent back to the consumer. At the consumer side we do the reverse of that process to regenerate whatever object was being returned by web service. That is the basic setup for Web services. Now, the notion of a client on one side, issuing a request and getting a result back, is the same as Web Page using a browser. Then what is the difference between these two? Well, it is very similar, but not same. Let us just compare the server browser model to the Web service model. It will be easy to see the distinction.

Web Page Has a User Interface Interacts with the user Works with web browser client

Web Services No User Interface Interacts with application Works with any type of client

Table 8.1 : Difference between Web page and Web services

142

Chapter 8 - Internet Programming

For the above table, a Web page has a user interface. That is main part of it. A Web service does not have user interface. A Web service is just between computer to computer applications. It is like a program on one computer calling a method that exists on another computer and calling it through the Internet. The Web page, since it has a user interface, it interacts with users. A Web service is designed to interact with applications. It is code that is going to call my Web service, not some user by clicking some button. On the Web-page side, naturally, a Web browser is the client. On the Web-service side, the client can be anything that can serialize a request and de-serialize the result that comes back. A fairly standard protocol called SOAP does it all. So now we know the difference. One thing that has to be mention here is. If we are building Web services using Visual Studio.NET and using the full-fledged Microsoft Internet Information Service, IIS, Web server. We have to place all our project files in C drives directory called Inetpub, and inside that, a directory called WWWRoot. WWWRoot directory is where all Web services are expected to be. Web services is a big topic. We will quickly mention a couple of other things under this topic. Those are:
l l l l l

Asynchronus Calls Exceptions Performance Security Evolution

A Web service can take a while to respond. When it is on the Internet, it has to do some computations. If the Web service calls some other service to get part of the answer or two or three other services to put together the response, that can take a few seconds. We normally do not want the client to freeze or block while waiting for response. .NET provides an easy way for us to make an asynchronous call. We can make the call to the Web service then carry on with whatever we want to do, while the Web service is churning away. We can then later find out when it returns and collect the response. Web service can throw an exception, and we handle it in our client code. We have already studied how these exceptions are caught in Advanced C# chapter, so we will not talk about it here. Performance issue would make a difference if, we make lots of Web service calls. There is some overhead to just making the call, so we would rather, keep our Web service interfaces chunky rather than chatty. It is better to make a few calls that deliver to you a lot of information. Security - The Web service can be completely insecure, when there is no authentication of user. Security plays a major role in internet domain. There are classes in .NET to address the security issue and authenticate users

BSIT 61 Basics of .NET

143

The last thing to mention here is that Web services, like Windows, are evolving a little bit. New techniques are adopted for the overall performance and efficiency of the web services.

8.2 WIN FORMS


With a Web Form, we have to use a browser. We can have browser to display a Web page that has some controls on it, and can have interaction with that Web page and Web service. ASP.NET provides us Web Forms for developing and running browser-based applications. It has a very rich set of GUI controls that we can use on our Web page. .Net provides all this in the form of WinForms. We can also put visual design on web page, we can specify a handler to be run back on the server, so the code behind the controls is done through server-side processing, and we can write that handler in any .NET language. We are now able to program our Web page in C# also. Nice thing about this is it allows separation of the design; the HTML is used for any type of Web page, and for the server-side code any .NET languages. To have a big picture for Win Forms, we will consider the following figure 8.2.

Web Form A B C

Event

Web Server IIS

Server Scripts
Click

Output Web page

Figure 8.2 : Web Form event handling process

This time the client really is a Web page. It has a title, it has got some of Web-enabled user interface devices, Web controls (textboxes and buttons). These controls are used to fire event against the machine that is serving the Web page. The user clicks a button, an event is fired, it goes through the Internet, it

144

Chapter 8 - Internet Programming

arrives over at the Web server like IIS. IIS has a couple of code files (server scripts) that have been compiled. When the event fires, the event handler runs on the Web server. A Web page is dynamically created with the result, and that is sent back to the user. This is the model for Web Forms, very similar to web services but here It is just that the client is a browser. There is a part of .NET called GDI+ which let us do fancy graphics, particularly in the area of WinForms. There are parts of the library for string processing, with file I/O. String processing plays a very important role in the web designing area. There are cryptography classes in .NET. and .NET Remoting, which provides a more general approach to reaching out through the Internet than just Web services.

8.3 ASP.NET
Before going to ASP.NET let us see what is ASP. ASP is a Microsoft Technology and it stands for Active Server Pages. ASP is a server side scripting technology that enables scripts (embedded in HTML pages) to be executed by an Internet server. ASP is a program that runs inside IIS (Internet Information Services). An ASP file can contain text, HTML, XML, and scripts. Scripts in an ASP file are executed on the server and an ASP file has the file extension .asp.

How Does it Work?


In case of a HTML file, when a browser requests an HTML file, the server returns the file. In case of ASP file, when a browser requests an ASP file, IIS passes the request to the ASP engine on the server. The ASP engine reads the file, line by line, and executes the scripts in the file. Finally, the ASP file is returned to the browser as plain HTML. Before we study ASP .NET, it would help to have a basic understanding of the above ASP technology. So now with this little information about ASP we will move to ASP.NET.

What is ASP.NET?
ASP.NET is the next generation ASP. ASP.NET is an entirely new paradigm for server-side ASP scripting. It is a part of the .NET Framework. ASP.NET is a unified Web development platform that provides the services necessary for us to build enterprise Web applications. While ASP.NET is largely syntax compatible with Active Server Pages (ASP), it provides a new programming model and infrastructure that allow us to create powerful applications. ASP.NET is part of the .NET Framework and allows us to take full advantage of the features of the common language runtime, such as type safety, inheritance, language interoperability, and versioning. This section provides conceptual information about how ASP.NET works, and shows us how to write code that takes full advantage of new platform. ASP.NET is not just the next version of Active Server Pages (ASP); it is a unified Web development

BSIT 61 Basics of .NET

145

platform that provides the services necessary for developers to build enterprise Web applications. ASP.NET provides a new programming model and infrastructure for more secure, scalable, and stable applications. We can upgrade our existing ASP applications by incrementally adding ASP.NET functionality to them. ASP.NET is a compiled, .NET-based environment; we can write applications in any .NET compatible language, including VisualBasic.NET, C#, and JScript .NET. Additionally, the entire .NET Framework is available to any ASP.NET application. Developers can easily use the benefits of these technologies, which include the managed CLR environment, type safety, inheritance, and so on. ASP.NET has been designed to work seamlessly with WYSIWYG (What You See Is What You Get) HTML editors and other programming tools, including Microsoft Visual Studio .NET. Not only it makes Web development easier, but it also provides all the benefits that tools offer, including a GUI that developers can use to drop server controls onto a Web page and fully integrated debugging support. Developers can choose the following two features when creating an ASP.NET application, Web Forms and Web services, or combine these in any way they want it. Each is supported by the same infrastructure that allows us to use authentication schemes, cache frequently used data, or customize our applications configuration.
l

Web Forms allows us to build powerful forms-based Web pages. When building these pages, we can use ASP.NET server controls to create common User Interface elements, and program them for common tasks. These controls allow us to rapidly build a Web Form by reusable components, simplifying the coding process. An XML Web service provides the means to access server functionality remotely. Using Web services, distributed applications can manipulate data between client and server applications to implement their business logic. XML Web services enable the exchange of data in client-server or server-server scenarios, using standards like HTTP and XML messaging to move data across internet. XML Web services are not bounded to a particular component technology or objectcalling convention. As a result, programs written in any language, using any component model, and running on any operating system can access XML Web services.

Writing Your First ASP.NET Page


ASP.NET pages are text files with an .aspx file extension. These pages consist of code and markup. They are dynamically compiled and executed on the server to respond the requesting client browser. When a browser client requests .aspx resources, the ASP.NET runtime parses and compiles the target file into a .NET Framework class. This class can then be used to dynamically process incoming clients requests. The .aspx file is compiled only the first time it is accessed; the compiled type instance is then reused across multiple requests. An ASP.NET page can be created simply by taking an existing HTML file and changing its file name extension to .aspx (no modification of code is required). For example, the following example demonstrates

146

Chapter 8 - Internet Programming

a simple HTML page that collects a users name and category preference and then performs a form post to the originating page when a button is clicked:
// exam1.aspx <html> <head> <link rel=stylesheet href=intro.css> </head> <body> <center> // Begin a form <form action=exam1.aspx method=post> <h3> Name: <input id=Name type=text> Category: <select id=Category size=1> <option>psychology</option> <option>business</option> <option>popular_comp</option> </select> <input type=submit value=Lookup> </h3> </form> // End a form </center> </body> </html>

The output will be as shown in below figure

Figure 8.3 : Output screen shot of exam1.aspx program

Nothing happens when we click the Lookup button. This is because the exam1.aspx file contains only static HTML (no dynamic content). Thus, the same HTML is sent back to the client when the button is clicked. In above output screen, if user enters the name as Anne, selects category as psychology and

BSIT 61 Basics of .NET

147

click Lookup button. The same html form is again presented to user with form fields (the text box and drop-down list) reset to their default values.

Adding Simple Code to a Page


ASP.NET provides syntax compatibility with existing ASP pages. This includes support for <% %> code blocks. The code listed between the <% and %> are executed to display data dynamically. This <% %> code blocks are intermixed with HTML content within an .aspx file. These code blocks execute in a top-down manner. The below example demonstrates how <% %> blocks can be used to loop over an HTML block (increasing the font size each time):
// exam2.aspx <%@ Page Language=C#%>//This line specify that the C# language is used for coding <html> <head> <link rel=stylesheethref=intro.css> </head> <body> <center> <form action=exam2.aspx method=post> <h3> Name: <input id=Name type=text> Category: <select id=Category size=1> <option>psychology</option> <option>business</option> <option>popular_comp</option> </select> </h3> <input type=submit value=Lookup> <p> <% for (int i=0; i <8; i++) { %> <font size=<%=i%>> Welcome to ASP.NET </font> <br> <% }%> </form> </center> </body> </html>

The output will be as shown in the below figure

148

Chapter 8 - Internet Programming

Figure 8.4 : Output screen shot of exam2.aspx program

When the button is clicked, the code between <% and %> is executed. As a result of it the Welcome to ASP.NET is printed 8 times in increasing order of their font size. In case of ASP the code within <% %> are interpreted. But in ASP.NET <% %> blocks are actually compiled, not interpreted using a script engine. This results in improved runtime execution performance. ASP.NET page developers can utilize <% %> code blocks to dynamically modify HTML output much as they can today with ASP. For example, the following example demonstrates how <% %> code blocks can be used to interpret results posted back from a client. The System.Web namespace supplies classes and interfaces that enable browser and server communication. This namespace includes the HttpRequest class which provides extensive information about the current HTTP request, the HttpResponse class which manages HTTP output to the client, and the HttpServerUtility class which provides access to server-side utilities and processes. System.Web also includes classes for cookie manipulation, file transfer, exception information, and output cache control. In the below example we use the Request.QueryString, which gets the collection of HTTP query string variables. These query string has form input values encoded within it. When the button is clicked the exam3.aspx file is executed at server. The server extracts these query string values and sends it to the client in HTML format. The client browser will print that message.

BSIT 61 Basics of .NET

149

// exam3.aspx <%@ Page Language=C# %> <html> <head> <link rel=stylesheethref=intro.css> </head> <body> <center> <form action=exam3.aspx> <h3> Name: <input name=Name type=text value= <%=HttpUtility.HtmlEncode(Request.QueryString[Name])%>> Category: <select name=Category size=1> <% String[] values = {psychology, business,popular_comp }; for (int i=0; i<values.Length; i++) { %> <option <% if (Request.QueryString[Category] == values[i]) { Response.Write(selected); } %>> <%=values[i]%> </option> <% } %> </select> </h3> <input type=submit name=Lookup value=Lookup> <p> <% if (Request.QueryString[Lookup] != null) { %> Hi <%=HttpUtility.HtmlEncode(Request.QueryString[Name]) %>, you selected: <%=HttpUtility.HtmlEncode(Request.QueryString[Category]) %> <% } %> </form> </center> </body> </html>

The output will be as shown in the below figure

150

Chapter 8 - Internet Programming

Figure 8.5 : Output screen shot of exam3.aspx program

While <% %> code blocks provide a powerful way to manipulate the text box output returned from an ASP.NET page.

Introduction to ASP.NET Server Controls


In addition to code and markup, ASP.NET pages can contain server controls, which are programmable server-side objects that typically represent a user interface element in the page, such as a textbox or image. Server controls simplify the problem of retaining state across round-trips to the server, automatically retaining their values across successive posts. Server controls are declared within an .aspx file using custom tags or intrinsic HTML tags that contain a runat=server attribute value. Intrinsic HTML tags are handled by one of the controls in the System.Web.UI.HtmlControls namespace. Any tag that does not explicitly map to one of the controls is assigned the type of System.Web.UI.HtmlControls.HtmlGenericControl. The following example uses four server controls: <form runat=server>, <asp:textbox runat=server>, <asp:dropdownlist runat=server>, and <asp:button runat=server>. At run time these server controls automatically generate HTML content.
// exam4.aspx <%@ Page Language=C#%> <html> <head> <link rel=stylesheethref=intro.css> </head> <body> <center> <form action=exam4.aspx method=post runat=server> <h3> Name: <asp:textbox id=Name runat=server/> Category: <asp:dropdownlist id=Category runat=server> <asp:listitem>psychology</asp:listitem> <asp:listitem>business</asp:listitem>

BSIT 61 Basics of .NET

151
<asp:listitem>popular_comp</asp:listitem> </asp:dropdownlist>

</h3> <asp:button text=Lookup runat=server/> </form> </center> </body> </html>

The output for the above program will be same as the output of very first example shown in figure 8.3. The only difference is, in that case the values entered where erased after clicking Lookup button but here in this program the values will be retained during the round trip to the server. These server controls automatically maintain any client-entered values between round trips to the server. This control state is not stored on the server (it is instead stored within an <input type=hidden> form field that is round-tripped between requests). Note also that no client-side script is required. In addition to supporting standard HTML input controls, ASP.NET enables developers to utilize richer custom controls on their pages. For example, the following example demonstrates how the <asp:adrotator> control can be used to dynamically display rotating ads on a page.
// exam5.aspx <%@ Page Language=C#%> <html> <head> <link rel=stylesheethref=intro.css> </head> <body> <center> <form action=exam5.aspx method=post runat=server> <asp:adrotator AdvertisementFile=ads.xml BorderColor=black BorderWidth=1 runat=server/> <h3> Name: <asp:textbox id=Name runat=server/> Category: <asp:dropdownlist id=Category runat=server> <asp:listitem>psychology</asp:listitem> <asp:listitem>business</asp:listitem> <asp:listitem>popular_comp</asp:listitem> </asp:dropdownlist> </h3> <asp:button text=Lookup runat=server/> </form> </center> </body> </html>

152
//ads.xml file <Advertisements>

Chapter 8 - Internet Programming

<Ad> <ImageUrl>images/banner1.gif</ImageUrl> <NavigateUrl>http://www.microsoft.com</NavigateUrl> <AlternateText>Alt Text</AlternateText> <Keyword>Computers</Keyword> <Impressions>80</Impressions> </Ad> <Ad> <ImageUrl>images/banner2.gif</ImageUrl> <NavigateUrl>http://www.microsoft.com</NavigateUrl> <AlternateText>Alt Text</AlternateText> <Keyword>Computers</Keyword> <Impressions>80</Impressions> </Ad> <Ad> <ImageUrl>images/banner3.gif</ImageUrl> <NavigateUrl>http://www.microsoft.com</NavigateUrl> <AlternateText>Alt Text</AlternateText> <Keyword>Computers</Keyword> <Impressions>80</Impressions> </Ad> </Advertisements>

The output will be as show in the figure below

Figure 8.6 : Output screen shot of exam5.aspx program

The above figure has rotating moments in the advertisement, which is not visible on this page.

BSIT 61 Basics of .NET

153

Handling Server Control Events


Each ASP.NET server control is capable of exposing an object model containing properties, methods, and events. ASP.NET developers can use this object model to cleanly modify and interact with the page. The following example demonstrates how an ASP.NET page developer can handle the OnClick event from the <asp:button runat=server> control to manipulate the Text property of the <asp:label runat=server> control.
// exam6.aspx <html> <head> <link rel=stylesheethref=intro.css> </head> <script language=C# runat=server> void SubmitBtn_Click(Object sender, EventArgs e) { Message.Text = Hi + HttpUtility.HtmlEncode(Name.Text) + , you selected: + Category.SelectedItem; } </script> <body> <center> <form action=exam6.aspx method=post runat=server> <asp:adrotator AdvertisementFile=ads.xml BorderColor=black BorderWidth=1 runat=server/> <h3> Name: <asp:textbox id=Name runat=server/> Category: <asp:dropdownlist id=Category runat=server> <asp:listitem>psychology</asp:listitem> <asp:listitem>business</asp:listitem> <asp:listitem>popular_comp</asp:listitem> </asp:dropdownlist> </h3> <asp:button text=Lookup OnClick=SubmitBtn_Click runat=server/> <p> <asp:label id=Message runat=server/> </form> </center> </body> </html> // ads.xml file <Advertisements> <Ad>

154

Chapter 8 - Internet Programming

<ImageUrl>images/banner1.gif</ImageUrl> <NavigateUrl>http://www.microsoft.com</NavigateUrl> <AlternateText>Alt Text</AlternateText> <Keyword>Computers</Keyword> <Impressions>80</Impressions> </Ad> <Ad> <ImageUrl>images/banner2.gif</ImageUrl> <NavigateUrl>http://www.microsoft.com</NavigateUrl> <AlternateText>Alt Text</AlternateText> <Keyword>Computers</Keyword> <Impressions>80</Impressions> </Ad> <Ad> <ImageUrl>images/banner3.gif</ImageUrl> <NavigateUrl>http://www.microsoft.com</NavigateUrl> <AlternateText>Alt Text</AlternateText> <Keyword>Computers</Keyword> <Impressions>80</Impressions> </Ad> </Advertisements>

The output will be as shown below

Figure 8.7 : Output screen shot of exam6.aspx program

This simple example given above is functionally equivalent to the exam3 example. But code is much cleaner and easier in this new server-control-based version. Finally before ending this section, we will see another example which takes number of columns and

BSIT 61 Basics of .NET

155

number of rows from the user through the select list and displays a table corresponding to that many rows and columns.
// exam7.aspx <script runat=server> submit(Object sender, EventArgs e) { int row, numrows, numcells, j, i; row = 0; numrows = rows1.Value; numcells = cells1.Value; for(j=1;j<=numrows;j++) { HtmlTableRow r = New HtmlTableRow(); row += 1; for(i=1; i<=numcells; i++) { HtmlTableCell c = New HtmlTableCell(); c.Controls.Add(New LiteralControl(row & j & , cell & i)); r.Cells.Add(c); } t1.Rows.Add(r); t1.Visible=true; } } </script> <html> <body> <form runat=server> <p>Table rows: <select id=rows1" runat=server> <option value=1">1</option> <option value=2">2</option> <option value=3">3</option> </select> <br />Table cells: <select id=cells1" runat=server> <option value=1">1</option> <option value=2">2</option> <option value=3">3</option> </select> <br /><br /> <input type=submit value=Display Table runat=server OnServerClick=submit>

156

Chapter 8 - Internet Programming

</p> <table id=t1" border=1" runat=server visible=false/> </form> </body> </html>

The output will be

SUMMARY
The .NET framework has extensible support for Internet-based programming. Web service is just a collection of methods that can be called from some other computer, from a remote location. Web Form use a browser to display a Web page that has some controls on it, and can have interaction with that Web page and Web service. ASP.NET is a unified Web development platform that provides the services necessary for us to build enterprise Web applications. ASP.NET pages are text files with an .aspx file extension. These pages consist of code and markup. They are dynamically compiled and executed on the server to respond to the requesting client.

QUESTIONS
1. 2. 3. 4. 5. 6. What is a web service? Explain its working. Who does the web service differ from web page? With a neat diagram explain the event handling process of win forms/web forms. What is ASP.NET? What is the use of ASP.NET? Write a program to display Welcome to ASP.NET 8 times in increasing order of their font size using ASP.NET. What is the role of System.Web? Write a program to demonstrate handling of server control events.

7. 8.

BSIT 61 Basics of .NET

157

Chapter 9

.NET Remoting

By the end of this chapter, you will have 8 8 8 An brief overview about .NET Remoting Knowledge about remoting process Learn how to program .NET remoting

9.1 OVERVIEW
What is .NET Remoting?
.NET Remoting enables application communication. Different applications can communicate with one another, whether those applications reside on the same computer, on different computers in the same local area network, or across the world in very different networks and even if the computers run different operating systems. The .NET Framework provides a number of services such as activation and lifetime control. It also provides communication channels responsible for transporting messages to and from remote applications. The messages can be encoded and decoded before they are sent along a channel. Applications can use binary encoding when the performance is critical. It can also use XML encoding when interoperability with other remoting systems is essential. Remoting was designed with security in mind, so we can serialize streams in order to secure them before they are transported over the channel.

BSIT 61 Basics of .NET

157

158

Chapter 9 - .NET Remoting

9.1.1 .NET Remoting, Distributed COM and Web Services


In this section we will compare all the three terminologies .NET Remoting, Distributed COM and Web services which all seems same.

.NET Remoting versus Distributed COM (DCOM)


In the past interprocess communication between applications was handled through Distributed Component Object Model, or simply DCOM. DCOM works well and the performance is adequate when applications exist on computers of similar type on the same network. However, DCOM has its drawbacks; it relies on a proprietary binary protocol that not all object models support. It also wants to communicate over a range of ports that are typically blocked by firewalls. These are two major drawbacks of DCOM. .NET Remoting eliminates the difficulties of DCOM by supporting different transport protocol formats and communication protocols. This allows .NET Remoting to be adaptable to the network environment in which it is being used.

.NET Remoting versus Web Services


When we read the description of .NET Remoting it reminds us a lot of what we have read about Web services. That is because Web services fall under the roof of .NET Remoting, but web services have a simplified programming model and are intended for a wide target audience. Web services involve allowing applications to exchange messages that may be platform independent and programming language independent. Web services know nothing about the client that is making the request. The clients communicate by transferring messages back and forth in a specific format known as the Simple Object Access Protocol, or SOAP The following list gives some of the major differences between .NET Remoting and Web services:
l

ASP.NET based Web services can only be accessed over HTTP. Whereas the .NET Remoting can be used across any protocol. Web services work in a stateless environment where each request results in a new object created to service the request. .NET Remoting supports state management options and can identify multiple calls from the same client. Web services serialize objects through XML contained in the SOAP messages and can thus only handle items that can be fully expressed in XML. .NET Remoting relies on the existence of the metadata within assemblies that contain information about data types. This limited metadata information is passed about an object, when it is passed by reference. Web services support interoperability across platforms and are good for heterogeneous environments. .NET Remoting requires the clients be built using .NET, which means a homogeneous environment.

BSIT 61 Basics of .NET

159

9.2 REMOTING PROCESS


Interprocess communication requires a server object whose functionality is to provide service to callers outside its process. A client that makes calls on the server object, and a transportation mechanism will be there from one end to the other. The addresses of server methods (services) are logical. These methods function properly in one process, but needs some mechanism to work on different client processes located remotely. One way for the client to call a server object is by making a copy of the object entirety and moves it to the client process, where the copys methods can be invoked directly. Many objects should not be copied and moved to some other process for execution because of many reasons. Firstly, extremely large objects with many methods can be poor choices for copying, to other processes. Usually, a client needs only the information returned by one or a few methods on the server object. Copying the entire server object, including vast amounts of internal information or executable structures unrelated to the clients needs, would be a waste of bandwidth as well as of client memory and processing time. Copying these objects could be a problem from security point of view. In these situations, the server process should pass to the client process a reference to the server object, not a copy of the object. Clients can use this reference to call the server object. These calls do not execute in the client process. Instead, the remoting system collects all information about the call and sends it to the server process, where it is interpreted, the required server object is located, and the call is made to the server object, by the server, on the client objects behalf. The result of the call is then sent back to the client process by the server. Remoting Architecture Using object references to communicate between server objects and clients is the heart of remoting. The remoting architecture, however, presents to the programmer an even simpler procedure. If we configure the client properly, we need only create a new instance of the remote object using new. Our client receives a reference to the server object, and we can then call its methods as though the object were in our process rather than running on a separate computer. The remoting system uses proxy objects to create the impression that the server object is in the clients process. Proxies are stand-in objects that present themselves as some other object. When our client creates an instance of the remote type, the remoting infrastructure creates a proxy object that looks to our client exactly like the remote type. Our client calls a method on that proxy, and the remoting system receives the call, routes it to the server process, invokes the server object, and returns the return value to the client proxy, which returns the result to the client. Remote calls must be conveyed in some way between the client and the server process. If we were building a remoting system ourselves, we might start by learning network programming and a wide array of protocols and serialization format specifications. But in the .NET Remoting system, the combination of underlying technologies required to open a network connection and use a particular protocol to send the bytes to the receiving application are represented as a transport channel.

160

Chapter 9 - .NET Remoting

A channel is a type that takes a stream of data, creates a package according to a particular network protocol, and sends the package to another computer. Some channels can only receive information, others can only send information, and still others, such as the default TcpChannel and HttpChannel classes, can be used in both directions. The client knows only that it wants a reference an object in another application domain on another computer. From the world outside the server application domain, the object is located by a URL. The URLs that represent unique types to the outside world are activation URLs, which ensure that our remote call is made to the proper type.

Complete Remoting System Design


Suppose we have an application running on one computer, and we want to use the functionality that is stored on another computer. The following figure shows the general remoting process.

SERVER

CLIENT

Figure 9.1 : Remoting process

When both the server and client are configured properly, a client creates a new instance of the server class. The remoting system creates a proxy object that represents the class and returns to the client object a reference to the proxy. When a client calls a method, the remoting system checks the type information, and sends the call over the channel to the server process. A listening channel picks up the request and forwards it to the server remoting system, which locates and calls the requested object. The process is then reversed, as the server remoting system bundles the response into a message and the server channel sends to the client channel. Finally, the client remoting system returns the result of the call to the client object through the proxy. Very little actual code is required to make this above concept work, but some thought should be given to the design and the configuration of the relationship. The code can be absolutely correct and but yet may fail if a URL or port number is incorrect.

BSIT 61 Basics of .NET

161

9.3 .NET REMOTING SAMPLE IMPLEMENTATION


In .NET Remoting, remote objects are accessed through Channels. Channels physically transport the messages to and from remote objects. There are two existing channels TcpChannel and HttpChannel, which use tcp and http protocols correspondingly

Create a Remotable Object


A remotable object is nothing more than an object that inherits from MarshalByRefObject. The following sample demonstrates a simple class hello world. This object has a single method HelloWorld that will return a string. The only values that can be returned from methods are the classes in the .NET Framework that are serializable such as string and DataSet. In addition, if we need to return a user-defined object then the object needs to be marked as serializable. In below example we have a class called SampleObject, which is a remote object for this .NET remoting example. We have to add in our program a reference to System.Runtime.Remoting, otherwise the TcpChannel will not be found. Compile the class and to get compiled code for this object.
using using using using System; System.Runtime.Remoting; System.Runtime.Remoting.Channels; System.Runtime.Remoting.Channels.Tcp;

namespace Remoting { // Sample remote object public class SampleObject : MarshalByRefObject { // Constructor public SampleObject() { } // Return a Hello world message public string HelloWorld() { return Hello World!; } } }

Create a Server to Expose the Remotable Object


We need to create a server object that will act as a listener to accept remote object requests. For this example we will use the TCP/IP channel. We first create an instance of the channel and then we have to register it for use by clients at a specific port. The service can be registered as

162

Chapter 9 - .NET Remoting

WellKnownObjectMode.SingleCall, which results in a new instance of the object for each client, or as WellKnownObjectMode.Singleton, which results in one instance of the object used for all clients. Since the service needs to be bound to an available port, In our example we use 8080, which is a unused port on the computer. We may need to choose a different port depending upon what ports that is available on the system (To see a list of the used ports on our computer open a command prompt and issue the command netstat a. It may produce a long listing so it is better making sure the command prompt buffer sizes are set to allow scrolling). We have to add a class called SampleServer, as shown in the following code. Add a reference to System.Runtime.Remoting, otherwise the TcpChannel will not be found as mentioned earlier. In addition, we have to add a reference to the previous program containing the SampleObject, otherwise the code will not compile because it wont know how to find a reference to SampleObject.
using using using using System; System.Runtime.Remoting; System.Runtime.Remoting.Channels; System.Runtime.Remoting.Channels.Tcp;

namespace Remoting { // Sample server public class SampleServer { public static int Main(string [] args) { // Create an instance of a channel TcpChannel channel = new TcpChannel(8080); ChannelServices.RegisterChannel(channel); // Register with the name HelloWorld RemotingConfiguration.RegisterWellKnownServiceType( typeof(SampleObject), HelloWorld, WellKnownObjectMode.SingleCall ); System.Console.WriteLine(Press the enter to exit...); System.Console.ReadLine(); return 0; } } }

Create a Client To Use the Remotable Object


Now that we have our remotable object and a server object to listen for requests, let us create a client to use it. Our client will be very simple. It will connect to the server, create an instance of the object using the server, and then execute the HelloWorld method.

BSIT 61 Basics of .NET

163

Here we have a class called SampleClient in the following code. Again we have to add a reference to System.Runtime.Remoting. In addition, add a reference to the program containing the SampleObject. Compile the class.
using using using using System; System.Runtime.Remoting; System.Runtime.Remoting.Channels; System.Runtime.Remoting.Channels.Tcp;

namespace Remoting { // Sample client public class SampleClient { public static int Main(string [] args) { // Create a channel for communicating with remote object // No port is specified on the client TcpChannel chan = new TcpChannel(); ChannelServices.RegisterChannel(chan); // Create an instance of the remote object SampleObject obj = (SampleObject) Activator.GetObject( typeof(Remoting.SampleObject),tcp://localhost:8080/HelloWorld ); // Use the object if( obj.Equals(null) ) { System.Console.WriteLine(Error: Cannot locate server); } else { Console.WriteLine(obj.HelloWorld()); } return 0; } } }

Test the Remoting Sample


Once we have created all the above code and successfully compiled each of them, we are ready to run it. Assuming we chose a free TCP/IP port for the service, start the server executable. After the server successfully starts it will display in a console window the message Press the enter key to exit. The server is listening so we are now ready to run the client. Executing the client should result in Hello World! being displayed in a separate console window. The client window will then close while the server remains open and available.

164

Chapter 9 - .NET Remoting

We can try the example in a network, by executing the server on one machine and the client on another. In order to run on separate machines we would need to change the reference to localhost in the sample client to point to the appropriate location.

SUMMARY
Different applications can communicate with one another, whether those applications reside on the same computer, on different computers in the same local area network, or across the world in very different networks and even if the computers run different operating systems using .NET Remoting. It is more complicated to program against than the Web services. We need to decide for ourselves whether our standard architecture is to use .NET Remoting or Web services. TcpChannel and HttpChannel classes are used to implement channel, this channel carries the messages between client and the server.

QUESTIONS
1. 2. 3. 4. 5. 6. What is a .NET remoting? How is .NET remoting different from web services and DCOM? Explain remoting architecture. With a neat diagram explain the remoting process. Explain the steps or phases involved in implementing .NET remoting applications. Write a program to display Hello World string to demonstrate .NET remoting.

BSIT 61 Basics of .NET

165

REFERENCES
1. PROFESSIONAL C# by Simon Robinson, Ollie Cornes, Jay Glynn, Burton Harvey, Craig Cornes, Jerod Moemeka, Christian Nagel, Morgan Skinner, Karli Watson, Wrox Press Ltd., July 2001 MSDN Library, www.microsoft.com/msdn http://www.microsoft.com/seminar/mmcfeed/mmcdisplay.asp?Lang=en&Product=103364&Audience=100402 http://www.dotnetspider.com/technology http://www.csharp-station.com

2. 3. 4. 5.

m m m

You might also like