Anda di halaman 1dari 232

O F F I C I A L

M I CRO S O F T

L EA RN I N G

PRO DU C T

10266A

Programming in C# with Microsoft Visual Studio 2010 Companion Content

Information in this document, including URL and other Internet Web site references, is subject to change without notice. Unless otherwise noted, the example companies, organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious, and no association with any real company, organization, product, domain name, e-mail address, logo, person, place or event is intended or should be inferred. Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation. Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property. The names of manufacturers, products, or URLs are provided for informational purposes only and Microsoft makes no representations and warranties, either expressed, implied, or statutory, regarding these manufacturers or the use of the products with any Microsoft technologies. The inclusion of a manufacturer or product does not imply endorsement of Microsoft of the manufacturer or product. Links may be provided to third party sites. Such sites are not under the control of Microsoft and Microsoft is not responsible for the contents of any linked site or any link contained in a linked site, or any changes or updates to such sites. Microsoft is not responsible for webcasting or any other form of transmission received from any linked site. Microsoft is providing these links to you only as a convenience, and the inclusion of any link does not imply endorsement of Microsoft of the site or the products contained therein. 2010 Microsoft Corporation. All rights reserved. Microsoft and the trademarks listed at http://www.microsoft.com/about/legal/en/us/IntellectualProperty/Trademarks/EN-US.aspx are trademarks of the Microsoft group of companies. All other marks are property of their respective owners.

Product Number: 10266A Released: 09/2010

Introducing C# and the .NET Framework

1-1

Module 1
Introducing C# and the .NET Framework
Contents:
Lesson 1: Introduction to the .NET Framework 4 Lesson 2: Creating Projects Within Visual Studio 2010 Lesson 3: Writing a C# Application Lesson 4: Building a Graphical Application Lesson 5: Documenting an Application Lesson 6: Debugging Applications by Using Visual Studio 2010 Module Review and Takeaways Lab Review Questions and Answers 2 5 9 12 17 20 22 24

1-2

Programming in C# with Microsoft Visual Studio 2010

Lesson 1

Introduction to the .NET Framework 4


Contents:
Question and Answers Additional Reading 3 4

Introducing C# and the .NET Framework

1-3

Question and Answers


What Is the .NET Framework 4?
Question: What is the purpose of the .NET Framework 4, and the three main components that it provides? Answer: The .NET Framework 4 provides a comprehensive development platform that offers a fast and efficient way to build applications and services. The .NET Framework 4 consists of three components: the common language runtime, the .NET Framework class library, and development frameworks.

The Purpose of Visual C#


Question: Which programming languages have you used? Answer: Ask students which languages they have used.

What Is an Assembly?
Question: Why would you choose to distribute an assembly rather than distribute the source code? Answer: An assembly is a compiled unit that can contain multiple functional components that is ready to run. If you distributed raw source files, end users would have to compile the code before they could run the application.

How the Common Language Runtime Loads, Compiles, and Runs Assemblies
Question: What steps does the CLR perform when you run your application? Answer: The CLR performs the following steps: 1. 2. 3. The Class Loader locates and loads all assemblies that the application requires. The assemblies will already be compiled into MSIL. The MSIL-to-native compiler verifies the MSIL code and then compiles all assemblies into machine code ready for execution. The Code Manager loads the executable assembly and runs the Main method.

What Tools Does the .NET Framework Provide?


Question: You have created two applications that both use an assembly called Contoso.ReportGenerator.dll. Both applications will run on the same machine. What is the best approach to share the Contoso.ReportGenerator.dll assembly and which tool would you use? Answer: You would install the assembly into the Global Assembly Cache (GAC) by using the Gacutil.exe tool.

1-4

Programming in C# with Microsoft Visual Studio 2010

Additional Reading
What Is the .NET Framework 4?
For more information about the .NET Framework, see the Microsoft .NET page at http://go.microsoft.com/fwlink/?LinkId=192876.

The Purpose of Visual C#


For more information about the Microsoft implementation of Visual C# 2010, see the Visual C# page http://go.microsoft.com/fwlink/?LinkId=192877. For more information about the new features of C# 4.0, see the What's New in Visual C# 2010 page at http://go.microsoft.com/fwlink/?LinkId=192878.

What Is an Assembly?
For more information about the purpose and features of assemblies, see the Assemblies in the Common Language Runtime page at http://go.microsoft.com/fwlink/?LinkId=192879. For more information about assembly versioning, see the Assembly Versioning page at http://go.microsoft.com/fwlink/?LinkId=192880. For more information about assembly signing, see the SignTool.exe (Sign Tool) page at http://go.microsoft.com/fwlink/?LinkId=192881.

What Tools Does the .NET Framework Provide?


For more information about the tools that the .NET Framework provides, see the .NET Framework Tools page at http://go.microsoft.com/fwlink/?LinkId=192882.

Introducing C# and the .NET Framework

1-5

Lesson 2

Creating Projects Within Visual Studio 2010


Contents:
Question and Answers Detailed Demo Steps 6 8

1-6

Programming in C# with Microsoft Visual Studio 2010

Question and Answers


Key Features of Visual Studio 2010
Question: What are the main reasons why you may choose Visual Studio 2010 over a text editor such as Notepad++? Answer: Answers should include: The intuitive IDE in Visual Studio 2010. Visual Studio 2010 supports rapid application development with Designer and Code Editor windows, and wizards. Visual Studio 2010 provides debugging features that help you fix any bugs in your code. Visual Studio 2010 offers help and support with IntelliSense, code snippets, and the Visual Studio community.

Templates in Visual Studio 2010


Question: What project templates would you use for each of the following: A client application that will run on a Windows-based computer. A library of functionality that you want to use in other applications. A Web site that you will host on an Internet Information Services (IIS) Web server.

Answer: Possible answers include: For a client application, you could use the WPF Application and Windows Forms Application templates. For a library, you could use the Class Library template. For a Web site, you could use the ASP.NET Web Application and ASP.NET MVC 2 Application templates.

The Structure of Visual Studio Projects and Solutions


Question: What role does the .sln file play in Visual Studio solutions? Answer: .NET solutions act as a wrapper for solution settings and your .NET projects. .NET solutions also enable you to build multiple projects without having to open multiple instances of Visual Studio.

Creating a .NET Framework Application


Question: What is the purpose of code snippets? Answer: Code snippets remove the need for developers to repeatedly type common code constructs.

Building and Running a .NET Framework Application


Question: Describe two ways to build and run a .NET Framework application.

Introducing C# and the .NET Framework

1-7

Answer: You can build a .NET application by using Visual Studio or csc.exe on the command line.

Demonstration: Disassembling a .NET Framework Assembly


Question: When developing a .NET Framework application, how would you find Ildasm useful? Answer: It is very useful to try to understand the inner workings of .NET, especially when you are developing your first .NET application. You can use Ildasm to inspect assemblies that you build and see how the compiler generates MSIL code.

1-8

Programming in C# with Microsoft Visual Studio 2010

Detailed Demo Steps


Demonstration: Disassembling a .NET Framework Assembly Demonstration Steps
Task 1: Run an existing .NET application
1. 2. 3. Right-click the Start menu, and then click Open Windows Explorer. In Windows Explorer, move to the E:\Demofiles\Mod1\Demo1 folder, and then double-click MyFirstApplication.exe. In the MyFirstApplication window, point out: 4. The title of the Command Prompt window, which is set to My First Application. The text Hello, this is my first .NET application which is displayed in the Command Prompt window. That the Command Prompt window does not automatically close until you click the X icon on the toolbar.

Close the MyFirstApplication window.

Task 2: Open Ildasm


1. 2. Right-click the Start menu, and then click Open Windows Explorer. In Windows Explorer, move to the C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin folder, and then double-click ildasm.exe.

Task 3: Disassemble an existing .NET Framework assembly


1. 2. In the Il Dasm window, on the File menu, click Open. In the Open dialog box, move to the E:\Demofiles\Mod1\Demo1 folder, and then double-click MyFirstApplication.exe.

Introducing C# and the .NET Framework

1-9

Lesson 3

Writing a C# Application
Contents:
Question and Answers Additional Reading 10 11

1-10

Programming in C# with Microsoft Visual Studio 2010

Question and Answers


What Are Classes and Namespaces?
Question: In your console application, you want to use the Console class, which is part of the System namespace. How do you bring the System namespace into scope? Answer: You could use the using statement to bring the System namespace into scope.

The Structure of a Console Application


Question: In your console application, you have a method called Main. What is the purpose of the Main method? Answer: The Main method provides an entry point into the console application.

Performing Input and Output by Using a Console Application


Question: Which two methods would you use to do the following: Display the message "Please press any key" on a new line. Capture the key that the user pressed.

Answer: The correct answer is: Console.WriteLine("Please press any key); ConsoleKeyInfo keyPressed = Console.ReadKey();

Best Practices for Commenting C# Applications


Question: Why is it important for you to comment your code? Answer: Answers should include: To improve the readability of your code. To capture the rationale behind your logic. To explain the purpose of elements in your code.

Introducing C# and the .NET Framework

1-11

Additional Reading
The Structure of a Console Application
For more information about command-line arguments, see the Main() and Command-Line Arguments (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192889.

Performing Input and Output by Using a Console Application


For more information about the Console class, see the Console Class page at http://go.microsoft.com/fwlink/?LinkId=192883.

1-12

Programming in C# with Microsoft Visual Studio 2010

Lesson 4

Building a Graphical Application


Contents:
Question and Answers Detailed Demo Steps Additional Reading 13 15 16

Introducing C# and the .NET Framework

1-13

Question and Answers


What Is WPF?
Question: Why would you choose to use WPF to create an application instead of Windows Forms? Answer: WPF enables you to create applications with much more compelling user interfaces, and offers greater control over user interface components.

The Structure of a WPF Application


Question: Can you think of any other markup languages that behave in a similar way to XAML? Answer: Web applications that use HTML.

The WPF Control Library


Question: You are building a simple form to capture user credentials and enable users to log on. Which controls could you use to build this form? Answer: Answers could include: For layout, use a Grid control. For labels for the user name and password, use Label controls. For input boxes for the user name and password, use TextBox controls. For a Submit button, use a Button control.

WPF Events
Question: When you develop your WPF applications, what two ways can you use to specify events for controls? Answer: Declaratively by using XAML markup, or imperatively in Visual C# code.

Building a Simple WPF Application


Question: What windows in Visual Studio 2010 do you typically use when you are building your applications? Answer: Answers should include: Solution Explorer Properties XAML Design Code Editor

1-14

Programming in C# with Microsoft Visual Studio 2010

Demonstration: Building a Simple WPF Application


Question: When developing a .NET Framework application, how would you find Ildasm useful? Answer: You can set properties by using the Properties window, or by editing the XAML for the control directly by using the XAML window.

Introducing C# and the .NET Framework

1-15

Detailed Demo Steps


Demonstration: Building a Simple WPF Application Demonstration Steps
Task 1: Create a new WPF application
1. 2. 3. On the Start menu, point to All Programs, click Microsoft Visual Studio 2010, and then click Microsoft Visual Studio 2010 - ENU. In Visual Studio 2010, on the File menu, click New, and then click Project. In the New Project dialog box, perform the following, and then click OK: a. b. c. In the center pane, click WPF Application. In the Name box, type MyFirstWpfApp In the Location box, type E:\Demofiles\Mod1\Demo2\Starter

Task 2: Add controls to the WPF application


1. 2. 3. On the View menu, click Toolbox. In the Toolbox window, double-click Button. Show students the control in the Design window, and the XAML markup in the XAML window.

Task 3: Set the properties for the controls


1. 2. 3. In the Design window, click the Button control. In the Properties window, set the Button property to ClickMeButton. In the Properties window, on the Properties tab, set the following properties: 4. FontSize: 20 Height: 50 Width: 150

In the XAML window, perform the following: In the Button element, set the Content attribute to Click Me. In the Window element, set the Height attribute to 150. In the Window element, set the Width attribute to 190.

1-16

Programming in C# with Microsoft Visual Studio 2010

Additional Reading
What Is WPF?
For more information about what WPF is, see the Introduction to WPF page at http://go.microsoft.com/fwlink/?LinkId=192884.

The WPF Control Library


For more information about the controls in the WPF control library, see the Control Library page at http://go.microsoft.com/fwlink/?LinkId=192886.

WPF Events
For more information about how WPF handles events, see the Events (WPF) page at http://msdn.microsoft.com/en-us/library/ms753115(VS.100).aspx.

Introducing C# and the .NET Framework

1-17

Lesson 5

Documenting an Application
Contents:
Question and Answers Additional Reading 18 19

1-18

Programming in C# with Microsoft Visual Studio 2010

Question and Answers


What Are XML Comments?
Question: Why would you use XML comments rather than standard comments? Answer: XML comments enable you to define comments in a more structured way. You can extract XML by using tools such as Sandcastle Help File Builder.

Common XML Comment Tags


Question: Which tag would you use to provide a detailed description of a method? Answer: The <remarks> tag.

Generating Documentation from XML Comments


Question: Which switch do you need to provide to get csc.exe to produce XML output? Answer: The /doc switch.

Introducing C# and the .NET Framework

1-19

Additional Reading
What Are XML Comments?
For more information about XML comments, see the XML Documentation Comments (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192887.

Common XML Comment Tags


For more information about XML comment tags, see the Recommended Tags for Documentation Comments (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192888.

Generating Documentation from XML Comments


For more information about Sandcastle Help File Builder, see the Sandcastle Help File Builder page at http://www.codeplex.com/SHFB.

1-20

Programming in C# with Microsoft Visual Studio 2010

Lesson 6

Debugging Applications by Using Visual Studio 2010


Contents:
Question and Answers 21

Introducing C# and the .NET Framework

1-21

Question and Answers


Debugging in Visual Studio 2010
Question: What are some of the debug functions that Visual Studio 2010 provides? Answer: Answers should include: Start/stop debugging. Halt on a breakpoint.

Using Breakpoints
Question: How would you use the debug functions in Visual Studio 2010 to debug your application and pause on a specific line of code? Answer: Answers should include: 1. 2. Locate the line of interest and set a breakpoint. Start the application with debugging.

Stepping Through and Over Code


Question: Why would you use the Step into and Step over debug functions? Answer: Answers should include: You would use Step into if you wanted to investigate the behavior in a particular method. You would use Step over if you didnt want to investigate the behavior of a method, but wanted to skip to the next line.

Using the Debug Windows


Question: Why would you use the Locals and Immediate windows when developing your application? Answer: Answers should include: You would use the Locals window to view and edit local (in-scope) variables. You would use the Immediate window to evaluate expressions, execute statements, and print out variable values.

1-22

Programming in C# with Microsoft Visual Studio 2010

Module Review and Takeaways


Review Questions
1. What is the purpose of the .NET Framework and the role of Visual C#? Answer: The .NET Framework 4 provides a comprehensive development platform that offers a fast and efficient way to build applications and services. C# is the language of choice for many developers. It uses a very similar syntax to C, C++, and Java, with several extensions and features designed for operation with the .NET Framework. 2. What is the purpose of Visual Studio 2010 templates? Answer: Visual Studio 2010 supports the development of different types of applications such as Windows-based client applications, Web-based applications, services, and libraries. To help you get started, Visual Studio 2010 provides several application templates that provide a structure for the different types of applications. 3. What is the purpose of Visual Studio projects and solutions? Answer: A project is used to organize source files, references, and project-level configuration settings that make up a single .NET Framework application or library. A single Visual Studio solution is a container for one or more projects. 4. What is the purpose of a Main method? Answer: Every .NET Framework application that compiles into an executable file must have a Main method. This method provides the CLR with an entry point into the application. When you run a .NET Framework application, the Main method is the first method that the CLR executes. 5. List some of the controls that WPF provides. Answer: Any of Button, Canvas, ComboBox, Grid, Label, StackPanel, and TextBox. 6. What is the purpose of XML comments? Answer: In Visual Studio 2010, you can add comments to your source code that will be processed to an XML file. This file can then be the input to a process that creates Help documentation for the classes in your code. 7. What is the purpose of the Visual Studio 2010 debugger? Answer: Debugging is an essential part of application development. You may notice errors as you write code, but some errorsespecially logic errorsmay only occur in specific circumstances that you do not test for. Users may report these errors to you, and you will have to correct them. Visual Studio 2010 provides several tools to help you debug code.

Best Practices Related to Writing a C# Application


Supplement or modify the following best practices for your own work situations: Keep the Main method small and lightweight. Declare variables by using meaningful names and avoid reference to the underlying data type, for example, nameString. Define controls by using meaningful names and avoid reference to the underlying control type, for example, labelName. Add comments to your code that describe your thought process.

Introducing C# and the .NET Framework

1-23

Tools
Tool Caspol.exe Use for Where to find it Enables users to modify the machine, user, and enterprise C:\Windows\Microsoft.NET\Frame security policy. This can include defining a custom work\v4.0.30319 permission set and adding assemblies to the full trust list. Enables users to manipulate the assemblies in the GAC. This can include installing and uninstalling assemblies in the GAC so that multiple applications can access them. Enables users to manipulate assemblies, such as determining whether an assembly is managed, or disassembling an assembly to view the compiled MSIL code. Enables users to create x.509 certificates for use in their development environment. Typically, you can use these certificates to sign your assemblies and define SSL connections. C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin

Gacutil.exe

Ildasm.exe

Makecert.exe

C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin

Ngen.exe

Enables users to improve the performance of .NET C:\Windows\Microsoft.NET\Frame applications. The Native Image Generator improves work\v4.0.30319 performance by precompiling assemblies into images that contain processor-specific machine code. The CLR can then run the precompiled images instead of using JIT compilation. Enables users to sign assemblies with strong names. The Strong Name Tool includes commands to create a new key pair, extract a public key from a key pair, and verify assemblies. C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin

Sn.exe

1-24

Programming in C# with Microsoft Visual Studio 2010

Lab Review Questions and Answers


1. What methods did you use to capture and display information in your console application? Answer: The static ReadLine and WriteLine methods. 2. What event did you handle on the Format Data button in your WPF application? Answer: The Click event handler. 3. What debugging functions did you use when you verified the application? Answer: Start Debugging, breakpoint, Step into, Step over, and the Immediate window. 4. How do you instruct Visual Studio 2010 to produce an XML file that contains XML comments? Answer: Set the XML documentation file property.

Using C# Programming Constructs

2-1

Module 2
Using C# Programming Constructs
Contents:
Lesson 1: Declaring Variables and Assigning Values Lesson 2: Using Expressions and Operators Lesson 3: Creating and Using Arrays Lesson 4: Using Decision Statements Lesson 5: Using Iteration Statements Module Review and Takeaways Lab Review Questions and Answers 2 5 8 11 14 16 17

2-2

Programming in C# with Microsoft Visual Studio 2010

Lesson 1

Declaring Variables and Assigning Values


Contents:
Question and Answers Additional Reading 3 4

Using C# Programming Constructs

2-3

Question and Answers


What Are Variables?
Question: What is a variable and how are variables used in Microsoft .NET Framework applications? Answer: Variables store values that the application requires in temporary memory locations. Applications process these values to perform functions such as calculations, data analysis, and database interactions.

What Are Data Types?


Question: What type would you use to store a sequence of alphanumeric characters? Answer: A String type.

Declaring and Assigning Variables


Question: What is the syntax for declaring and assigning a variable? Answer: One possible answer is DataType variableName = Value;.

What Is Variable Scope?


Question: You are developing an application and you need to declare a variable that is accessible to two methods in the same class. What is the easiest way to achieve this? Answer: Use class scope and declare a private field at the class level. Use class scope and declare a private field at the class level.

Converting a Value to a Different Data Type


Question: You are converting a string to an int type, but you are unsure whether the string will contain a valid int value. Which conversion approach should you use? Answer: You should use the int.TryParse method.

Read-Only Variables and Constants


Question: What are the main differences between a constant and a read-only variable? Answer: Answers should include the following: The declaration keyword, const and readonly. Constants can only be initialized at compile time, whereas you can initialize a read-only variable at run time. You can initialize a read-only variable at its declaration or in the class constructor, whereas you can only initialize a constant at its declaration.

2-4

Programming in C# with Microsoft Visual Studio 2010

Additional Reading
Declaring and Assigning Variables
For more information about the keyword in C#, see the C# Keywords page at http://go.microsoft.com/fwlink/?LinkId=192890. For more information about naming conventions, see the General Naming Conventions page at http://go.microsoft.com/fwlink/?LinkId=192891. For more information about capitalization conventions, see the Capitalization Conventions page at http://go.microsoft.com/fwlink/?LinkId=192892.

What Is Variable Scope?


For more information about scopes, see the 3.7 Scopes page at http://go.microsoft.com/fwlink/?LinkId=192893.

Converting a Value to a Different Data Type


For more information about the System.Convert class, see the Convert Class page at http://go.microsoft.com/fwlink/?LinkId=192894.

Read-Only Variables and Constants


For more information about constants, see the const (C# Reference) page at http://go.microsoft.com/fwlink/?LinkId=192895.

Using C# Programming Constructs

2-5

Lesson 2

Using Expressions and Operators


Contents:
Question and Answers Additional Reading 6 7

2-6

Programming in C# with Microsoft Visual Studio 2010

Question and Answers


What Is an Expression?
Question: What is the value of the expression "99" + "1"? Answer: The string, 991.

What Are Operators?


Question: Which operator would you use to calculate the remainder after dividing one integer value by another? Answer: The % operator.

Specifying Operator Precedence


Question: How can you control the order of processing in an expression? Answer: Use parentheses to override the precedence of operators. Expressions in the parentheses are evaluated first.

Best Practices for Performing String Concatenation


Question: Why is concatenating strings considered bad practice, and how can you avoid it? Answer: Concatenating strings is considered bad practice because strings are immutable. This means that every time you concatenate a string, you create a new string in memory. To avoid this problem, concatenate strings by using the StringBuilder class.

Using C# Programming Constructs

2-7

Additional Reading
What Are Operators?
For more information about the operator in C#, see the C# Operators page at http://go.microsoft.com/fwlink/?LinkId=192896, and the Operators (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192897

Best Practices for Performing String Concatenation


For more information about the StringBuilder class, see the StringBuilder Class page at http://go.microsoft.com/fwlink/?LinkId=192898.

2-8

Programming in C# with Microsoft Visual Studio 2010

Lesson 3

Creating and Using Arrays


Contents:
Question and Answers Additional Reading 9 10

Using C# Programming Constructs

2-9

Question and Answers


What Is an Array?
Question: What is an array, and why would you want to use arrays in a C# application? Answer: An array is a set of elements that are grouped together and managed as a unit. Arrays enable you to handle a set of closely related data.

Creating and Initializing Arrays


Question: How do you declare a multidimensional array? Answer: Answers should resemble the following code example.
Type[ , ] arrayName = new Type[ Size1, Size2 ];

Common Properties and Methods Exposed by Arrays


Question: What members would you use to locate the last element in an array, and then change that elements value? Answer: Use the following code example to illustrate the answer.
int[] oldNumbers = { 1, 2, 3, 4, 5 }; oldNumbers.SetValue(5000, oldNumbers.Length -1);

Accessing Data in an Array


Question: Explain two approaches to accessing data in an array. Answer: Answers should include two of the following: Indexer GetValue() Explicit GetEnumerator() Implicit GetEnumerator()

2-10

Programming in C# with Microsoft Visual Studio 2010

Additional Reading
Creating and Initializing Arrays
For more information about arrays, see the Multidimensional Arrays section on the Harness the Features of C# to Power Your Scientific Computing Projects page at http://go.microsoft.com/fwlink/?LinkId=192899. For more information about single-dimensional arrays, see the Single-Dimensional Arrays (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192900. For more information about multidimensional arrays, see the Multidimensional Arrays (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192901. For more information about jagged arrays, see the Jagged Arrays (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192902.

Common Properties and Methods Exposed by Arrays


For more information about the System.Array class, see the Array Class page at http://go.microsoft.com/fwlink/?LinkId=192903.

Using C# Programming Constructs

2-11

Lesson 4

Using Decision Statements


Contents:
Question and Answers Additional Reading 12 13

2-12

Programming in C# with Microsoft Visual Studio 2010

Question and Answers


Using One-Way If Statements
Question: When must you enclose the code in the body of an if statement in braces? Answer: You must enclose the code in the body of an if statement in braces if you want to perform more than one statement. It is also good practice even if you only use a single statement because you may need to add additional statements later.

Using Either-Or If Statements


Question: Think of a scenario where you may want to use the if else statement and discuss. Answer: This question is designed to stimulate discussion among the students, so there is no definitive answer. However, one possible answer could be to prompt a user for input and test whether the input is valid. If it is valid, process the input; if it is invalid, display an error message.

Using Multiple-Outcome If Statements


Question: What is the purpose of the else statement in an else if construct? Answer: The else statement is the default block and should contain logic that will be executed if none of the conditions in the previous if and else if conditions return false.

Using the Switch Statement


Question: With the exception of the default case, is the order of the cases in a switch statement important? Answer: No. You cannot fall through from one case to another, so the order in which they occur is immaterial.

Guidelines for Choosing a Decision Construct


Question: Which statement would you use to perform an action based on the possible values of a single variable? Answer: The switch statement.

Using C# Programming Constructs

2-13

Additional Reading
Using Either-Or If Statements
For more information about the ?: operator, see the ?: Operator (C# Reference) page at http://go.microsoft.com/fwlink/?LinkId=192904.

2-14

Programming in C# with Microsoft Visual Studio 2010

Lesson 5

Using Iteration Statements


Contents:
Question and Answers 15

Using C# Programming Constructs

2-15

Question and Answers


Types of Iteration Statements
Question: Which iteration statement would you use to prompt a user for a valid response? Answer: The most suitable loop for this scenario is the do loop, although there are many alternative solutions. Get students to justify their answers.

Using the While Statement


Question: When using the while loop, what type must the condition expression evaluate to? Answer: The [condition] can be any expression that evaluates to a Boolean value.

Using the Do Statement


Question: What is the minimum number of iterations that a do loop will perform? Answer: One, because the condition is evaluated at the end of the loop.

Using the For Statement


Question: What are the four components of a for loop? Answer: Answers should include the following: A numeric variable to use for the counter (this can be a variable that is already defined or a variable that was defined as part of the loop specification). A starting value for the counter variable. A limit for the counter variable. Instructions for how to modify the counter variable at the end of each iteration.

Break and Continue Statements


Question: What is the difference between the break and continue statements? Answer: The break statement enables you to exit the loop entirely, and skip to the next line of code outside the loop. The continue statement is similar to the break statement except that, instead of exiting the loop entirely, you simply skip the remaining code in the current iteration, test the condition, and then start the next iteration of the loop.

2-16

Programming in C# with Microsoft Visual Studio 2010

Module Review and Takeaways


Review Questions
1. If you declare a variable with the type var, what does it mean? Answer: It means that it is an implicit variable where the data type is inferred by the initializers value. 2. How can you control the order of processing in an expression? Answer: You can use parentheses to control the order of processing in an expression. 3. What is the purpose of arrays? Answer: An array is a set of objects that are grouped together and managed as a unit. 4. Name an alternative approach to using the if else statements. Answer: Using either the switch statement or the ?: operator. 5. Which loop construct should you use to execute a block of code one or more times? Answer: The do loop.

Best Practices Related to Using C# Constructs


Supplement or modify the following best practices for your own work situations: When you choose a data type, ensure that you select one that is appropriate to the type of data that you are processing. For example, do not create a double variable for processing integer data because this requires that the compiler generates additional code to convert your integer data into double values. Instead of concatenating strings by using the + operator, use the StringBuilder class or use the static Format method of the String class. When you access elements in an array by using the index of an element, make sure that you test to see whether the index exists. If the index doesnt exist, you will get an IndexOutOfRange exception. Avoid too many nested if else and loop statements because they can make debugging your applications complicated. Avoid using break and continue statements in loops unless you really need them.

Using C# Programming Constructs

2-17

Lab Review Questions and Answers


1. Which .NET Framework class and method did you use to calculate the square root? Answer: The Math class and the Sqrt method. 2. Which .NET Framework class did you use to construct the string that represented the binary number, and what benefits does this class provide? Answer: The StringBuilder class, which enables you to dynamically build a string without the overhead of concatenating several string variables. 3. Which loop construct did you use to iterate through all of the rows in the matrix1 array, and why was it a good choice? Answer: I used the for loop. This was a good choice because I knew how many rows were in the array.

Declaring and Calling Methods

3-1

Module 3
Declaring and Calling Methods
Contents:
Lesson 1: Defining and Invoking Methods Lesson 2: Specifying Optional Parameters and Output Parameters Module Review and Takeaways Lab Review Questions and Answers 2 9 12 13

3-2

Programming in C# with Microsoft Visual Studio 2010

Lesson 1

Defining and Invoking Methods


Contents:
Question and Answers Detailed Demo Steps Additional Reading 3 5 8

Declaring and Calling Methods

3-3

Question and Answers


What Is a Method?
Question: Why do you need to use methods when developing a .NET Framework application with C#? Answer: All code must belong to a method. If you dont define methods, you cannot implement behavior. In addition, all C# programs must have at least one method called Main, which defines the starting point for the application.

Creating a Method
Question: What are the four elements in the method specification? Answer: The four elements are: Access modifier Return type Method name Parameter list

Calling a Method
Question: How can you call the method in the following code example?
void DeleteReport(string reportName)

Answer: Answers should resemble the following code example. Users should specify the method name and a string parameter, and there is no return value.
DeleteReport("MyReport");

Creating and Calling Overloaded Methods


Question: What is meant by overloading a method? Answer: Overloading is the ability to define several methods with the same name in the same class, provided each method has a different signature.

Using Parameter Arrays


Question: How do you define a method that takes a parameter array? Answer: You need to do the following: The parameter array must be the last parameter in the parameter list. You must prefix the parameter with the params keyword. The parameter must be an array.

3-4

Programming in C# with Microsoft Visual Studio 2010

Refactoring Code into a Method


Question: Why would you want to refactor code into a method? Answer: When you need to perform the same logic several times in different places.

Testing a Method
Question: Why would you want to use unit tests when developing your .NET Framework applications? Answer: Unit tests provide an excellent way to help simplify the testing process and ensure that your tests are reliable and easily repeatable.

Demonstration: Refactoring and Testing a Method


Question: Name one way in which you can view and start your unit tests. Answer: Answers can include: In the Test View window. In the Test Results window. On the Test menu.

Declaring and Calling Methods

3-5

Detailed Demo Steps


Demonstration: Refactoring and Testing a Method Demonstration Steps
Task 1: Open the existing application and view the existing code
1. 2. 3. Click Start, point to All Programs, click Microsoft Visual Studio 2010, and then click Microsoft Visual Studio 2010. In Visual Studio 2010, on the File menu, click Open, and then click Project/Solution. In the Open Project dialog box, move to the E:\Demofiles\Mod3\Demo1\Starter\MethodRefactorAndTestDemo folder, and then doubleclick MethodRefactorAndTestDemo.sln. In Solution Explorer, in the MethodRefactorAndTestDemo.sln project, right-click the Program.cs file, and then click View Code. Explain that the Main method includes some code to generate an array of random numbers based on the following three constraints: Minimum number for any of the random numbers. Maximum number for any of the random numbers. Number of random numbers required. 6. Explain that you want to use this code elsewhere in your application, so you are going to refactor it into a new method.

4. 5.

Task 2: Refactor an existing code block


1. In the Code Editor window, in the Main method, select the code in the following code example.
int[] randomNumbers = new int[numberOfRequirednumbers]; Random numberGenerator = new Random(); for (int count = 0; count < numberOfRequirednumbers; count++) { randomNumbers[count] = numberGenerator.Next(min, max); }

2. 3.

Right-click the selected code block, point to Refactor, and then click Extract Method. In the Extract Method dialog box, perform the following, and then click OK: a. b. In the New method name box, type GenerateRandomNumbers In the Preview method signature box, show students the proposed signature for the method (the int[] return type, and three int parameters).

4.

Show students the new GenerateRandomNumbers method, and the GenerateRandomNumbers method call.

Task 3: Generate a unit test for the GenerateRandomNumbers method


1. 2. In the Code Editor window, right-click the GenerateRandomNumbers method, and then click Create Unit Tests. In the Create Unit Tests dialog box, perform the following, and then click OK:

3-6

Programming in C# with Microsoft Visual Studio 2010

a. b. 3. 4.

In the Current selection list, show students the available components in the project. In the Output project list, explain that if the solution already contained a test project, you could select it here.

In the New Test Project dialog box, click Create. In the Add InternalsVisibleTo Attribute dialog box, click Yes.

Task 4: Examine the auto-generated unit test method


1. 2. In the Code Editor window, in the ProgramTests class, navigate to the GenerateRandomNumbersTest method. Show students the following: The [TestMethod()] method attribute. Explain that all test methods are decorated with this attribute. The declaration of the min, max, and numberOfRequiredNumbers variables that the GenerateRandomNumbers method requires. The Assert.AreEqual statement to test the result that is returned from the GenerateRandomNumbers method.

Task 5: Modify the auto-generated unit test method


1. Make the following changes to the GenerateRandomNumbersTest method: Set the max variable to 100. Set the numberOfRequirednumbers variable to 999. Remove the int[] expected = null; // TODO: Initialize to an appropriate value line. Replace the Assert.AreEqual(expected, actual); line with Assert.AreEqual(1000, actual.Length); Remove the Assert.Inconclusive("Verify the correctness of this test method."); line. Your code should resemble the following code example.
public void enerateRandomNumbersTest() { int min = 0; // TODO: Initialize to an appropriate value int max = 100; // TODO: Initialize to an appropriate value int numberOfRequirednumbers =999; // TODO: Initialize to an appropriate value int[] actual; actual = Program_Accessor.GenerateRandomNumbers(min, max, numberOfRequirednumbers); Assert.AreEqual(1000, actual.Length); }

2.

On the Build menu, click Build Solution.

Task 6: Run the unit test


1. 2. On the Test menu, point to Windows, and then click Test View In the Test View window, right-click the GenerateRandomNumbersTest row, and then click Run Selection.

Declaring and Calling Methods

3-7

3.

Show students the Test Results window, and that the unit test failed for the following reason: Failed GenerateRandomNumbersTest TestProject1 Assert.AreEqual failed. Expected:<1000>. Actual:<999>.

4. 5. 6.

In the Code Editor window, navigate to the GenerateRandomNumbersTest method, and then set the numberOfRequirednumbers variable to 1000. In the Test View window, right-click the GenerateRandomNumbersTest row, and then click Run Selection. Show students the Test Results window, and that the unit test succeeded.

3-8

Programming in C# with Microsoft Visual Studio 2010

Additional Reading
Creating a Method
For more information about methods, see the Methods (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192905.

Creating and Calling Overloaded Methods


For more information about method overloading, see the Member Overloading page at http://go.microsoft.com/fwlink/?LinkId=192906.

Using Parameter Arrays


For more information about parameter arrays, see the params (C# Reference) page at http://go.microsoft.com/fwlink/?LinkId=192907.

Refactoring Code into a Method


For more information about refactoring in C#, see the Refactoring (C#) page at http://go.microsoft.com/fwlink/?LinkId=192908.

Declaring and Calling Methods

3-9

Lesson 2

Specifying Optional Parameters and Output Parameters


Contents:
Question and Answers Additional Reading 10 11

3-10

Programming in C# with Microsoft Visual Studio 2010

Question and Answers


What Are Optional Parameters?
Question: When defining a method with optional parameters, in what order must you specify the parameters? Answer: You must specify all mandatory parameters before optional parameters.

Calling a Method by Using Named Arguments


Question: What is the syntax for using named parameters in method calls?
Answer: methodName(parameterName1 : value1, parameterName2 : value2);

What Are Output Parameters?


Question: What happens if you attempt to call MyMethod with the code in the following code example?
MyMethod(10, 101.1F, 20);

Answer: Your code will not compile. You must provide an argument that can hold a value, such as a variable, and you must specify the out keyword.

Declaring and Calling Methods

3-11

Additional Reading
What Are Optional Parameters?
For more information about optional parameters, see the Named and Optional Arguments (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192909.

What Are Output Parameters?


For more information about output parameters, see the out parameter modifier (C# Reference) page at http://go.microsoft.com/fwlink/?LinkId=192910.

3-12

Programming in C# with Microsoft Visual Studio 2010

Module Review and Takeaways


Review Questions
1. What return type do you specify for a method that does not return any data? Answer: void 2. What term is given to the process of defining multiple methods with the same name, but different parameter lists? Answer: Method overloading. 3. What is the difference between an optional parameter and a named argument? Answer: An optional parameter is part of a method signature, and specifies that a parameter has a default value. When an application invokes the method, it can omit the argument that corresponds to this parameter and the method will use the default value instead. A named argument is the syntax that an application can use when it invokes a method. An application can specify the arguments in any order by prefixing them with the name of the parameter that they should be used for. 4. What is the purpose of output parameters? Answer: Output parameters enable you to return multiple values from a method.

Best Practices Related to Using Methods


Supplement or modify the following best practices for your own work situations: Keep methods as small and lightweight functional units. If methods start to become large, consider refactoring code into smaller logical methods. Create unit tests for all public methods. You can assume that any private methods that you create will be tested when the public methods are called. Use output parameters only when it is absolutely necessary. If you find yourself using output parameters too often, reconsider the purpose of the method.

Declaring and Calling Methods

3-13

Lab Review Questions and Answers


1. When using output parameters in a method, what must you do before the method completes? Answer: You must assign a value to the parameter, otherwise the code will not compile. 2. When adding optional parameters to an existing method signature, why will your code run successfully without making changes to any of the existing method calls? Answer: When you add optional parameters, you provide default values. If you do not explicitly set the optional parameters in your method calls, the default parameters will be used. 3. When creating a unit test method in a Visual Studio test project, what attribute must you decorate your test method with? Answer: The TestMethod attribute.

Handling Exceptions

4-1

Module 4
Handling Exceptions
Contents:
Lesson 1: Handling Exceptions Lesson 2: Raising Exceptions Module Review and Takeaways Lab Review Questions and Answers 2 8 10 11

4-2

Programming in C# with Microsoft Visual Studio 2010

Lesson 1

Handling Exceptions
Contents:
Question and Answers Detailed Demo Steps Additional Reading 3 5 7

Handling Exceptions

4-3

Question and Answers


What Is an Exception?
Question: Discuss your experiences of applications that have crashed with other students and the instructor. Answer: This question is designed to stimulate discussion among the students, so there is no definitive answer. Students should think about all of the applications that they have used that have behaved unexpectedly or crashed. You can then point out that the developer failed to handle such conditions.

Using a Try/Catch Block


Question: How would you use the try/catch block to catch all exceptions regardless of type, and then execute some generic additional logic? Answer: To catch all exceptions, you could use the code in the following code example.
try { // Your logic. } catch { // Logic to execute in the event of an exception. }

Using Exception Properties


Question: You have a catch block that contains some logic to write details of any exceptions to a log file. The catch block will catch all types of exceptions. What members of the exception class would you use to get a description and the source of the error? Answer: The Message and Source properties.

Using a Finally Block


Question: Describe the differences between a catch block and a finally block. Answer: A catch block contains code that executes only when a matching exception is thrown. A finally block contains code that always executes, regardless of whether an exception is thrown.

Using the Checked and Unchecked Keywords


Question: In what scenario would you want to use the checked keyword? Answer: By default, overflow checking is enabled. You may want to use the checked keyword if overflow checking has been disabled during compilation or in the runtime.

4-4

Programming in C# with Microsoft Visual Studio 2010

Demonstration: Raising Exceptions in Visual Studio


Question: How can you guarantee that Visual Studio will always notify you if an exception occurs instead of automatically propagating the exception to a catch block? Answer: You can use the Exceptions dialog box to configure the exception as Thrown instead of User-Handled.

Handling Exceptions

4-5

Detailed Demo Steps


Demonstration: Raising Exceptions in Visual Studio Demonstration Steps
Task 1: Open the existing application and view the existing code
1. 2. 3. Click Start, point to All Programs, click Microsoft Visual Studio 2010, and then click Microsoft Visual Studio 2010. In Visual Studio 2010, on the File menu, click Open, and then click Project/Solution. In the Open Project dialog box, move to the E:\Demofiles\Mod4\Demo1\Starter\FabrikamUserManagement folder, and then doubleclick FabrikamUserManagement.sln. In the Code Editor window, point to the Main method and explain the following: a. b. c. d. e. The Main method contains a call to the Users.GetUserById method, which returns a user object for the provided user ID. If you specify a user ID that does not exist, the method returns null. When the method returns, the application displays the userName field returned. The method call is in a try/catch block. The catch block contains code to display details of any exceptions to the Command Prompt window.

4.

Task 2: Run the application and examine how it currently handles exceptions
1. 2. 3. On the Debug menu, click Start Debugging. Switch to the Command Prompt window, and show students the Object reference not set to an instance of an object message. Explain that you got this message because a user could not be found with the ID of 5, so the GetUserById method returned null. Subsequently, any code that tries to use that user object will generate a null reference exception. Explain that, because the code is enclosed in a try/catch block, the exception was caught and error logic was executed. Explain that you can alter the behavior of Visual Studio so that your code will stop executing whenever an exception is thrown. Currently, Visual Studio is configured so that you can catch exceptions and handle them yourself, such as with a try/catch block. On the Debug menu, click Stop Debugging.

4. 5.

6.

Task 3: Modify the exception configuration in Visual Studio to always throw exceptions
1. 2. 3. On the Debug menu, click Exception. In the Exceptions dialog box, in the Break when an exception is list, expand Common Language Runtime Exceptions, and then expand System. Explain that, by using this list and the associated Thrown and User-unhandled check boxes, you can control how Visual Studio notifies you when an exception is generated.

4-6

Programming in C# with Microsoft Visual Studio 2010

4. 5. 6. 7.

Explain that the code in our application generated a null reference exception, so that is the type of exception that we will modify. In the Break when an exception is list, under System, locate the System.NullReferenceException row. For the System.NullReferenceException row, clear the User-unhandled check box, and then select the Thrown check box. In the Exceptions dialog box, click OK.

Task 4: Rerun the application and examine the different behavior


1. 2. 3. On the Debug menu, click Start Debugging. Explain that this time, when the application tries to use the user object and generates a null reference exception, Visual Studio stops the application and notifies you. Explain that you can then use the debug Step Over function to walk through the logic in the catch block.

Handling Exceptions

4-7

Additional Reading
Using a Try/Catch Block
For more information about try/catch blocks, see the try-catch (C# Reference) page at http://go.microsoft.com/fwlink/?LinkId=192911.

Using Exception Properties


For more information about the members in the System.Exception class, see the Exception Members page at http://go.microsoft.com/fwlink/?LinkId=192912.

Using a Finally Block


For more information about finally block, see the try-finally (C# Reference) page at http://go.microsoft.com/fwlink/?LinkId=192913.

Using the Checked and Unchecked Keywords


For more information about using the checked and unchecked keywords, see the Checked and Unchecked (C# Reference) page at http://go.microsoft.com/fwlink/?LinkId=192914.

4-8

Programming in C# with Microsoft Visual Studio 2010

Lesson 2

Raising Exceptions
Contents:
Question and Answers 9

Handling Exceptions

4-9

Question and Answers


Creating an Exception Object
Question: You are in the process of adding several new methods to your application. So far you have added the method signatures. What else should you do to indicate that the method is not complete and functional? Answer: You should throw a NotImplementedException exception. Syntax for throwing an exception is covered in the next topic.

Throwing an Exception
Question: Where does execution continue after you perform a throw statement? Answer: The next catch block in the call stack.

Best Practices for Handling and Raising Exceptions


Question: In your application, you have a method that returns a user object. When you have the user object, you are going to use it as a parameter in another method call. There is a possibility that some of the data in the user object is incorrectly formatted and that, if you try to use this data, it would cause an exception. What would you do in this situation? Answer: The point here is that you shouldnt rely on exception handling for normal processing. In this example, it would be best to test whether the data is in the correct format before processing, rather than just hoping it works and doesnt throw an exception. Explain that, in some scenarios, this can be a tough decision.

4-10

Programming in C# with Microsoft Visual Studio 2010

Module Review and Takeaways


Review Questions
1. In your application, you have a method call that depends on many variables that are out of the control of your application. It is very likely that this method call will throw an exception. You have implemented a centralized exception-handling system so that all exceptions are caught and handled in a single place. When you make the method call, if an exception is thrown, you just want to ensure that you manage and close any resources. Which construct would you use? Answer: The try/finally construct. 2. In your application, you have defined several custom exception classes. You have several catch blocks that catch this type of exception. In your catch blocks, you want to wrap this type of exception in a more generic exception type. What constructor parameter can you set to ensure that the more specific exception is included in the chain? Answer: The InnerException parameter. 3. What should you do with detailed exception messages? Answer: Log them because they will help you diagnose problems in your application. Do not display them to the user.

Best Practices Related to Implementing Exception Handling


Supplement or modify the following best practices for your own work situations: Always design your applications with errors in mind. Users will always find ways to break your application. Design your exception handling in such a way that all exceptions are handled in a centralized location. Do not design your application to rely on exceptions to function normally. Do not display detailed exception messages to the user because a malicious user could use detailed technical information to make your application malfunction.

Handling Exceptions

4-11

Lab Review Questions and Answers


1. What construct did you use to make the method calls fail-safe? Answer: The try/catch block. 2. What attribute did you need to decorate the test method with so that it expected an exception? Answer: The ExpectedException attribute, specifying the type of exception expected. 3. What keyword can you use to explicitly instruct the compiler or runtime to check for overflow exceptions? Answer: The checked keyword.

Reading and Writing Files

5-1

Module 5
Reading and Writing Files
Contents:
Lesson 1: Accessing the File System Lesson 2: Reading and Writing Files by Using Streams Module Review and Takeaways Lab Review Questions and Answers 2 5 8 9

5-2

Programming in C# with Microsoft Visual Studio 2010

Lesson 1

Accessing the File System


Contents:
Question and Answers Additional Reading 3 4

Reading and Writing Files

5-3

Question and Answers


Manipulating Files
Question: In your application, you use files as a temporary storage mechanism while the application is running. When the application stops running, you want to make sure that the file exists, and then delete the file. What is the easiest way to achieve this? Answer: The easiest approach would be to use the static Exists and Delete methods of the File class.

Reading from and Writing to Files


Question: In your application, you have just added some logic to handle exceptions. You now want to extend this logic further to store details of these exceptions to a log file on the file system so that you can diagnose any problems. You will be writing a string variable and you should want to never overwrite any existing log records in a file. Which method would you use? Answer: The AppendAllText method.

Manipulating Directories
Question: What class would you use to retrieve an instance of a directory in the file system, which you can then interact with? Answer: You would create an instance of the DirectoryInfo class by using the default constructor passing in the path to the directory.

Manipulating Paths
Question: You are creating a filter that enables users to browse files by extension. To start with, you need to get the extensions of each file and then run some logic depending on the result. You also want to display the file name including the extension in a list. Which methods would you use to query the files? Answer: The GetExtension and GetFileName methods.

Using the Common File System Dialog Boxes


Question: You have almost completed your implementation of a text editor, and the final step is to get users to browse to a save location, and prompt them for a file name. What class would you use and how would you use it? Answer: You would use the SaveFileDialog class in the following way: 1. 2. 3. 4. Create an instance of the SaveFileDialog class. Set any properties to customize its behavior. Call the ShowDialog method to show the dialog box. Use the result returned in the FileName property.

5-4

Programming in C# with Microsoft Visual Studio 2010

Additional Reading
Manipulating Files
For more information about the File class, see the File Class page at http://go.microsoft.com/fwlink/?LinkId=192915. For more information about the FileInfo class, see the FileInfo Class page at http://go.microsoft.com/fwlink/?LinkId=192916.

Manipulating Directories
For more information about the Directory class, see the Directory Class page at http://go.microsoft.com/fwlink/?LinkId=192917. For more information about the DirectoryInfo class, see the DirectoryInfo Class page at http://go.microsoft.com/fwlink/?LinkId=192918.

Manipulating Paths
For more information about the Path class, see the Path Class page at http://go.microsoft.com/fwlink/?LinkId=192919.

Reading and Writing Files

5-5

Lesson 2

Reading and Writing Files by Using Streams


Contents:
Question and Answers Additional Reading 6 7

5-6

Programming in C# with Microsoft Visual Studio 2010

Question and Answers


What Are Streams?
Question: What do you think are the benefits of streaming data? Answer: Answers should include: The ability to read and write large amounts of data without consuming resources such as memory and network bandwidth. Not needing to load the entire amount of data into memory. Enabling your application to handle any amount of data, regardless of size.

Reading and Writing Binary Data


Question: Why is it important to close streams when you have finished using them? Answer: To release any file handles, and flush data to the underlying streams.

Reading and Writing Text


Question: You want to write a series of strings to a text file, and add a line break after each string. What is the easiest way to achieve this? Answer: Write the string by using the WriteLine method of the StreamWriter class.

Reading and Writing Primitive Data Types


Question: What method would you use to read a 64-bit signed integer from a binary stream? Answer: The ReadInt64() method.

Reading and Writing Files

5-7

Additional Reading
What Are Streams?
For more information about the FileStream class, see the FileStream Class page at http://go.microsoft.com/fwlink/?LinkId=192920.

Reading and Writing Text


For more information about the StreamWriter class, see the StreamWriter Class page at http://go.microsoft.com/fwlink/?LinkId=192921. For more information about the StreamReader class, see the StreamReader Class page at http://go.microsoft.com/fwlink/?LinkId=192922.

Reading and Writing Primitive Data Types


For more information about the BinaryWriter class, see the BinaryWriter Class page at http://go.microsoft.com/fwlink/?LinkId=192923. For more information about the BinaryReader class, see the BinaryReader Class page at http://go.microsoft.com/fwlink/?LinkId=192924.

5-8

Programming in C# with Microsoft Visual Studio 2010

Module Review and Takeaways


Review Questions
1. When you write data to a stream, name two methods that you could use to ensure that any buffered data is written to the underlying data source. Answer: You could call the Flush or Close methods. 2. Which two classes does the .NET Framework provide that display a graphical control that enables you to capture a save file and open file path from a user? Answer: The SaveFileDialog and OpenFileDialog classes. 3. Which stream class would you use to write textual data? Answer: The StreamWriter class.

Best Practices Related to Reading and Writing Data on the File System
Supplement or modify the following best practices for your own work situations: Always check to make sure that the file exists before you try to read from it or write to it. Do not assume that the contents in the file are going to be correct. Remember that files are stored on the file system, which users have access to. Users are more than capable of editing a file that they should not edit. Always parse a file to ensure that it is valid, or be prepared to catch and handle an appropriate exception. When you use streams, always ensure that you close the stream after use to ensure that you release any handles on the underlying data source. It is easy to assume that you will have permissions to write and read files anywhere in the live environment. Typically, this is not the case. Make sure that your development environment mirrors the live environment.

Reading and Writing Files

5-9

Lab Review Questions and Answers


1. Explain the purpose of the File.Load and File.Save static methods. Answer: You call the File.Load method passing the file path as the parameter. The method returns a string that contains the full contents of the file. You call the File.Save method passing the file path and text content as parameters. The text content parameter is stored in a file at the file path on the hard disk. 2. You have a file that contains text. You want to read the file one character at a time. Which method of the StreamReader class would you use? Answer: The Read method.

Creating New Types

6-1

Module 6
Creating New Types
Contents:
Lesson 1: Creating and Using Enumerations Lesson 2: Creating and Using Classes Lesson 3: Creating and Using Structures Lesson 4: Comparing References to Values Module Review and Takeaways Lab Review Questions and Answers 2 5 9 11 15 16

6-2

Programming in C# with Microsoft Visual Studio 2010

Lesson 1

Creating and Using Enumerations


Contents:
Question and Answers Additional Reading 3 4

Creating New Types

6-3

Question and Answers


What Are Enumerations?
Question: Discuss with other students and the instructor where and how you have used enumerations before. Answer: This question is designed to stimulate discussion among the students, so there is no definitive answer.

Creating New Enum Types


Question: Does the following code example show a legal enumeration?
enum Season : sbyte {Spring = -3, Summer, Fall, Winter};

Answer: Yes. The signed byte type allows negative numbers. The value assigned to Spring is 3, Summer has the value 2, Fall has the value 1, and Winter has the value 0.

Initializing and Assigning Enum Variables


Question: Describe how to initialize an enumeration variable. Answer: You should do the following: Specify the type of enumeration. Specify the name of the instance. Assign a value by using the = operator.

6-4

Programming in C# with Microsoft Visual Studio 2010

Additional Reading
Creating New Enum Types
For more information about enumerations, see the Enumeration Types (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192925.

Creating New Types

6-5

Lesson 2

Creating and Using Classes


Contents:
Question and Answers Additional Reading 6 8

6-6

Programming in C# with Microsoft Visual Studio 2010

Question and Answers


What Is a Class?
Question: Explain the difference between a class and an object. Answer: A class is a blueprint that defines the characteristics of an object, such as the data that the object can contain and the operations that the object can perform. An object is an instance of a class. You can use a single class to create as many objects as your application requires.

Adding Members to Classes


Question: What is the difference between a field and a method? Answer: Fields hold data whereas methods expose functionality.

Defining Constructors and Initializing an Object


Question: What happens if you do not define a default constructor for a class? Answer: If you do not define any constructors, a default parameterless constructor will be provided. If you define one or more constructors, a default parameterless constructor will not be provided.

Creating Objects
Question: Which operator must you use when you initialize a class to create an instance of that class? Answer: The new operator.

Accessing Class Members


Question: Highlight the syntax errors in the following code example.
Car myCar = new Car("Ford", "Black"); // Set a field to indicate the car's transmission. myCar,isManual() = true; // Call a method to calculate the car's value. double value = myCar,CalculateValue;

Answer: The following code example highlights the errors.


Car myCar = new Car("Ford", "Black"); // Set a field to indicate the car's transmission. myCar,isManual() = true; // Comma should be period, and no parentheses. // Call a method to calculate the car's value. double value = myCar,CalculateValue; // Comma should be period, and parentheses required.

Creating New Types

6-7

Using Partial Classes and Partial Methods


Question: What happens if you define a partial method, but do not provide an implementation of this method? Answer: Your code will still compile and run, and you will be able to call the method. However, because the method contains no implementation, it will not do anything.

6-8

Programming in C# with Microsoft Visual Studio 2010

Additional Reading
Defining Constructors and Initializing an Object
For more information about constructors, see the Instance Constructors (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192926.

Using Partial Classes and Partial Methods


For more information about partial classes and methods, see the Partial Classes and Methods (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192927.

Creating New Types

6-9

Lesson 3

Creating and Using Structures


Contents:
Question and Answers 10

6-10

Programming in C# with Microsoft Visual Studio 2010

Question and Answers


What Are Structures?
Question: Is the following code legal?
int x = 99; System.Int32 y = x + 1;

Answer: Yes. It is legal because the int type is an alias for the System.Int32 type.

Defining and Using a Structure


Question: What keyword do you use to declare a structure? Answer: The struct keyword.

Initializing a Structure
Question: You decide to add further constructors to the Currency type, and you attempt to factor out common initialization code into a method in the type, as shown in the following code example. Why does this approach not work?
struct Currency { public string currencyCode; // The ISO 4217 currency code public string currencySymbol; // The currency symbol ($,,...) public int fractionDigits; // The number of decimal places public Currency(string code) { this.initialize(); this.currencyCode = code; } public Currency(string code, string symbol) { this.initialize(); this.currencyCode = code; this.currencySymbol = symbol; } // Specify default values // Constructors may override these values public void initialize() { this.currencyCode = "USD"; this.currencySymbol = "$"; this.fractionDigits = 2; } };

Answer: Before you can call any methods in a structure, you must ensure that all of the fields in the structure have been initialized. Consequently, you cannot call methods in a constructor to initialize fields in that structure, so this code will not compile. Note that this code would be legal if the Currency type was a class.

Creating New Types

6-11

Lesson 4

Comparing References to Values


Contents:
Question and Answers Additional Reading 12 14

6-12

Programming in C# with Microsoft Visual Studio 2010

Question and Answers


Comparing Reference Types to Value Types
Question: If Residence is a class (a reference type), what message does the following code example display?
Residence myHouse = new Residence(ResidenceType.House, 2); Residence anotherHouse = new Residence(ResidenceType.House, 2); if (myHouse == anotherHouse) { Console.WriteLine("They are the same house"); } else { Console.WriteLine("They are different houses"); }

Answer: The message They are different houses is displayed because they are different objects, although both are of type Residence. If the Residence type was a struct, the code would not compile unless the Residence definition included an implementation for the == operator.

Passing a Value Type by Reference into a Method


Question: In the following code example, what is the value of the myString variable after the ChangeInput method completes?
class Program { static void Main(string[] args) { string myString = "Original value"; ChangeInput(myString); } static void ChangeInput(string input) { input = "Changed value"; } }

Answer: The value of the myString variable is Original Value. The issue is that the reference is passed as the parameter. You can change data through the reference, but if you make the reference refer somewhere else, it is lost when the method completes, and the original data is left intact.

Boxing and Unboxing


Question: Is the following code an example of boxing or unboxing?
object amount = "1234"; int convertedAmount = (int)amount;

Answer: Unboxing.

Creating New Types

6-13

Nullable Types
Question: What is wrong with the following code?
int amount = null; if (amount != null) { ... }

Answer: The int variable amount has not been declared by using the nullable int type. The following code example illustrates this.
int? i = null;

6-14

Programming in C# with Microsoft Visual Studio 2010

Additional Reading
Passing a Value Type by Reference into a Method
For more information about using the ref keyword, see the ref (C# Reference) page at http://go.microsoft.com/fwlink/?LinkId=192928.

Boxing and Unboxing


For more information about boxing and unboxing, see the Boxing and Unboxing (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192929.

Creating New Types

6-15

Module Review and Takeaways


Review Questions
1. When you define the first value in an enumeration, the value defaults to the index of zero. How can you change the default index? Answer:
enum Days : int { Monday = 1, Tuesday = 2, Wednesday = 3 };

2.

What is a class? Answer: A class is a blueprint from which you can create objects. A class defines the characteristics of an object, such as the data that the object can contain and the operations that the object can perform.

3.

What keyword can you use to split a class definition over multiple files? Answer: The partial keyword.

4.

Is a Boolean variable a value type or a reference type? Answer: A value type.

5.

How can you pass a value type by reference into a method? Answer: By using the ref keyword.

6.

What is the process called when you explicitly convert a value type to a reference type? Answer: Boxing.

Best Practices Related to Creating and Using Types


Supplement or modify the following best practices for your own work situations: When you use a series of related constants, create an enumeration to encapsulate those constants into an object. Use structures to implement simple concepts whose main feature is their value. Also use structures for small data items where it is just asor nearly asefficient to copy the value as it would be to copy an address. Use classes for more complex data that is too big to copy efficiently.

6-16

Programming in C# with Microsoft Visual Studio 2010

Lab Review Questions and Answers


1. What type would you use to model a collection of constant values? Answer: An enumeration type. 2. At what scope level would you define an enumeration type, if you wanted that type to be accessible to multiple classes? Answer: At the namespace scope level. 3. What construct would you use to model a simple custom numeric type? Answer: A struct type.

Encapsulating Data and Methods

7-1

Module 7
Encapsulating Data and Methods
Contents:
Lesson 1: Controlling Visibility of Type Members Lesson 2: Sharing Methods and Data Module Review and Takeaways Lab Review Questions and Answers 2 5 9 10

7-2

Programming in C# with Microsoft Visual Studio 2010

Lesson 1

Controlling Visibility of Type Members


Contents:
Question and Answers Additional Reading 3 4

Encapsulating Data and Methods

7-3

Question and Answers


What Is Encapsulation?
Question: Discuss your experiences of encapsulation with other students. Answer: This question is designed to stimulate discussion among the students, so there is no definitive answer.

Comparing Private and Public Members


Question: You have created a class called Product to encapsulate information about the products that your organization sells. The following code example shows the definition of this class. You want to use this class in an application that creates Product objects and displays their details. What is the main problem with the Product class that may mean that a client application cannot use the Product type in this way? Answer: The constructor is private, so you cannot instantiate a Product object to use any of its public instance members.
public class Product { // Make these fields private so that an application cannot change // them after the Product object has been created. private int productID; private string productName; // Public methods that a client application can use to // get the product ID and name. public int GetProductID() { return this.productID; } public string GetProductName() { return this.productName; } // Provide a constructor to enable a client application // to create a Product object. Product(int ID, string name) { this.productID = ID; this.productName = name; } }

Comparing Internal and Public Types


Question: In the Revenue structure that is shown in the preceding code example, the constructor is defined as public although the type is defined as private. Does this mean that a type other than the Sales type can invoke this constructor? Answer: The Revenue struct is only accessible to the Sales type.

7-4

Programming in C# with Microsoft Visual Studio 2010

Additional Reading
What Is Encapsulation?
For more information about encapsulation, see the Classes and Structs (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192935.

Comparing Private and Public Members


For more information about the private access modifier, see the private (C# Reference) page at http://go.microsoft.com/fwlink/?LinkId=192930. For more information about the public access modifier, see the public (C# Reference) page at http://go.microsoft.com/fwlink/?LinkId=192931.

Comparing Internal and Public Types


For more information about the internal access modifier, see the internal (C# Reference) page at http://go.microsoft.com/fwlink/?LinkId=192932.

Encapsulating Data and Methods

7-5

Lesson 2

Sharing Methods and Data


Contents:
Question and Answers Additional Reading 6 8

7-6

Programming in C# with Microsoft Visual Studio 2010

Question and Answers


Creating and Using Static Fields
Question: What happens if you try to access a public static field through an instance of the type? Answer: You get a compile error that explains that the member cannot be accessed with an instance reference.

Creating and Using Static Methods


Question: The Person class definition in the following code example contains functionality to calculate the number of years that a person must work before he or she reaches a set retirement age. The class does not compile; can you identify the problem?
class Person { public int retirementAge; public Person(int retirementAge) { this.retirementAge = retirementAge; } public static int CalculateRemainingWorkYears(int age) { return (retirementAge - age); } }

Answer: The CalculateRemainingWorkYears method is static, but the retirementAge field is an instance.

Creating Static Types and Using Static Constructors


Question: Identify the errors in the class definition in the following code example.
static class Person { int ageLimit; private static Person(int ageLimit) { this.ageLimit = ageLimit; } public static string[] GetAllNames() { throw new NotImplementedException(); } }

Answer: The class has the following errors: You cannot explicitly set an access modifier on a static constructor. The constructor must be parameterless. A static constructor cannot access an instance field.

Encapsulating Data and Methods

7-7

Creating and Using Extension Methods


Question: Briefly explain the difference between a standard method's signature and a signature for an extension method. Answer: An extension method must be static; the first parameter represents the type that you want to extend and is prefixed with the this keyword.

7-8

Programming in C# with Microsoft Visual Studio 2010

Additional Reading
Creating and Using Static Methods
For more information about the static modifier, see the static (C# Reference) page at http://go.microsoft.com/fwlink/?LinkId=192933.

Creating and Using Extension Methods


For more information about extension methods, see the Extension Methods (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192934.

Encapsulating Data and Methods

7-9

Module Review and Takeaways


Review Questions
1. Briefly explain the purpose of encapsulation. Answer: The purpose of encapsulation is to hide the internal data and implementation details of a type, so that only specific parts of the type are accessible to applications. 2. Which access modifier do you use to expose a method to a type in a different assembly? Answer: The public access modifier. 3. How do you invoke a static constructor? Answer: You do not explicitly invoke static constructors. The common language runtime (CLR) invokes them before you use the static type.

Best Practices Related to Encapsulating Data and Methods


Supplement or modify the following best practices for your own work situations: Do not expose the inner workings of your types with the public and internal access modifiers. If in doubt, use the private access modifier. If a type does not need to store instance data, declare the type as static. If you must add functionality to an existing type and do not want to derive a new type, use extension methods.

7-10

Programming in C# with Microsoft Visual Studio 2010

Lab Review Questions and Answers


1. What access modifier would you use to stop fields being accessed from outside the parent type? Answer: The private access modifier. 2. When declaring a constructor in a static type, how many parameters can the constructor take? Answer: The constructor must be parameterless. 3. When declaring an extension method, what keyword must you use to prefix the first parameter? Answer: The this keyword.

Inheriting from Classes and Implementing Interfaces

8-1

Module 8
Inheriting from Classes and Implementing Interfaces
Contents:
Lesson 1: Using Inheritance to Define New Reference Types Lesson 2: Defining and Implementing Interfaces Lesson 3: Defining Abstract Classes Module Review and Takeaways Lab Review Questions and Answers 2 8 13 19 20

8-2

Programming in C# with Microsoft Visual Studio 2010

Lesson 1

Using Inheritance to Define New Reference Types


Contents:
Question and Answers Detailed Demo Steps Additional Reading 3 5 7

Inheriting from Classes and Implementing Interfaces

8-3

Question and Answers


What Is Inheritance?
Question: What accessor should you use to make class members accessible to child classes? Answer: The protected accessor. The protected accessor permits access to the current class and classes that inherit from it only.

The .NET Framework Inheritance Hierarchy


Question: What types inherit from the Object class? Answer: All types inherit from the Object class, including reference and value types.

Overriding and Hiding Methods


Question: What happens if you attempt to hide a method without using the new keyword? Answer: The compiler will assume that you meant to hide the existing method and your code will compile; however, the compiler will generate a warning suggesting that you use the new keyword.

Calling Methods and Constructors in a Base Class


Question: What happens if you do not call the constructor of a base class in the constructor for your class? Answer: The compiler automatically calls the default constructor of the base class. If the base class does not have a public default constructor, the code will not compile.

Assigning and Referencing Classes in an Inheritance Hierarchy


Question: What exception is thrown if you attempt to perform an invalid cast? Answer: An InvalidCastException exception is thrown at run time if you attempt to perform an invalid cast.

Understanding Polymorphism
Question: When you reference an object by its parent class, which version of a method is called: the version from the base class, or the overridden version in the child class? Answer: When a method is overridden in the child class, the version in the child class will always be used. Referencing an object by using the parent class will not change this behavior.

Defining Sealed Classes and Methods


Question: Can you define a class that inherits from the C# int type? Answer: No. The int type is a value type; it is implicitly sealed.

8-4

Programming in C# with Microsoft Visual Studio 2010

Demonstration: Using Inheritance to Construct New Reference Types


Question: What tools does Visual Studio provide to help when you implement an interface? Answer: Visual Studio includes the Implement Interface Wizard, which adds method stubs for interface members to your class.

Inheriting from Classes and Implementing Interfaces

8-5

Detailed Demo Steps


Demonstration: Using Inheritance to Construct New Reference Types Demonstration Steps
1. Start the 10266A-GEN-DEV virtual machine, and then log on by using the following credentials: User name: Student Password: Pa$$w0rd 2. Open Microsoft Visual Studio 2010: Click Start, point to All Programs, click Microsoft Visual Studio 2010, and then click Microsoft Visual Studio 2010. 3. Open the Module 8, Demo1 starter solution: a. b. 4. In Visual Studio, on the File menu, point to Open, and then click Project/Solution. Move to the E:\Demofiles\Mod8\Demo1\Starter\UsingInheritanceDemo folder, and then double-click UsingInheritanceDemo.sln.

Add a Television class to the Program.cs file: a. b. In Solution Explorer, double-click Program.cs. Add the following code to the file.
class Television { }

5.

Add a protected virtual method named SetCurrentChannel to the Television class. The method should write a message to the console indicating that the channel has been set. Your code should resemble the following code example.
class Television { protected virtual void SetCurrentChannel() { Console.WriteLine(Channel set.); } }

6.

Add a protected method named TurnOn to the Television class. The method should write a message to the console indicating that the television is on. Your code should resemble the following code example.
class Television { protected virtual void SetCurrentChannel() { Console.WriteLine(Channel set.). } protected void TurnOn() { Console.WriteLine(Television on.); }

8-6

Programming in C# with Microsoft Visual Studio 2010

7.

Add to the Program.cs file a WidescreenTV class that inherits from the Television class: Add the code in the following code example to the file.
class WidescreenTV : Television { }

8.

Override the SetCurrentChannel method. The method should write a message to the screen indicating that the channel has been set on the widescreen television. Your code should resemble the following code example.
class WidescreenTV : Television { protected override void SetCurrentChannel() { Console.WriteLine(Widescreen channel set.); } }

9.

Add a constructor to the WidescreenTV class. The constructor should call the constructor of the base class, call the TurnOn method, call the SetCurrentChannel method, and then call the SetCurrentChannel method of the base class. Your code should resemble the following code example.
class WidescreenTV : Television { protected override void SetCurrentChannel() { Console.WriteLine(Widescreen channel set.); } public WidescreenTV() : base() { TurnOn(); SetCurrentChannel(); base.SetCurrentChannel(); } }

10. Uncomment the code in the Program class that creates an instance of the WidescreenTV class. 11. Run the application with debugging and verify that the following messages appear: Television on. Widescreen channel set. Channel set.

12. On the Debug menu, click Start Without Debugging.

Inheriting from Classes and Implementing Interfaces

8-7

Additional Reading
The .NET Framework Inheritance Hierarchy
For more information about the Object class, see the Object Class page at http://go.microsoft.com/fwlink/?LinkId=192936.

Assigning and Referencing Classes in an Inheritance Hierarchy


For more information about the as operator, see the as (C# Reference) page at http://go.microsoft.com/fwlink/?LinkId=192941. For more information about the is operator, see the is (C# Reference) page at http://go.microsoft.com/fwlink/?LinkId=192942.

Understanding Polymorphism
For more information about polymorphism, see the Polymorphism (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192937.

8-8

Programming in C# with Microsoft Visual Studio 2010

Lesson 2

Defining and Implementing Interfaces


Contents:
Question and Answers Detailed Demo Steps Additional Reading 9 10 12

Inheriting from Classes and Implementing Interfaces

8-9

Question and Answers


What Is an Interface?
Question: Can you add a default implementation of a method to an interface? Answer: No. An interface only contains definitions for methods and other class members; it does not contain any implementation. Default implementations can be added to abstract classes, which are covered later in this module.

Creating and Implementing an Interface


Question: When you define an interface, do you add a method body? Answer: No. An interface only contains a method definition. You replace the method body with a semicolon.

Referencing an Object Through an Interface


Question: What happens if you attempt to cast an object to an interface that it does not implement? Answer: Just like object casting, this will cause an InvalidCastException exception.

Explicitly and Implicitly Implementing an Interface


Question: What is the advantage of explicit implementation? Answer: You can implement several interfaces that may have members that have the same names and return types without introducing ambiguity.

Demonstration: Creating an Interface


Question: What is the recommended naming convention when defining interfaces? Answer: Interface names should be prefixed with an uppercase I.

8-10

Programming in C# with Microsoft Visual Studio 2010

Detailed Demo Steps


Demonstration: Creating an Interface Demonstration Steps
1. Open Visual Studio 2010: Click Start, point to All Programs, click Microsoft Visual Studio 2010, and then click Microsoft Visual Studio 2010. 2. Open the Module 8, Demo2 starter solution: a. b. 3. In Visual Studio, on the File menu, point to Open, and then click Project/Solution. Move to the E:\Demofiles\Mod8\Demo2\Starter\CreatingAnInterfaceDemo folder, and then double-click CreatingAnInterfaceDemo.sln.

Add an ITelevision interface to the Program.cs file: a. b. In Solution Explorer, double-click Program.cs. Add the code in the following code example to the file.
interface ITelevision { }

4.

Add a TurnOn method to the interface. Your code should resemble the following code example.
interface ITelevision { void TurnOn(); }

5.

Add a TurnOff method to the interface. Your code should resemble the following code example.
interface ITelevision { void TurnOn(); void TurnOff(); }

6.

Add an IncreaseVolume method to the interface. Your code should resemble the following code example.
interface ITelevision { void TurnOn(); void TurnOff(); void IncreaseVolume(); }

7.

Add a DecreaseVolume method to the interface. Your code should resemble the following code example.

Inheriting from Classes and Implementing Interfaces

8-11

interface ITelevision { void TurnOn(); void TurnOff(); void IncreaseVolume(); void DecreaseVolume(); }

8.

Add to the Program.cs file a Television class that implements the ITelevision interface: Add the code in the following code example to the file.
class Television : ITelevision { }

9.

In the definition of the Television class, implement the ITelevision interface by using the tools in Visual Studio: Right-click ITelevision, point to Implement Interface, and then click Implement Interface.

8-12

Programming in C# with Microsoft Visual Studio 2010

Additional Reading
Explicitly and Implicitly Implementing an Interface
For more information about how to explicitly implement interface members, see the Explicit Interface Implementation (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192938.

Inheriting from Classes and Implementing Interfaces

8-13

Lesson 3

Defining Abstract Classes


Contents:
Question and Answers Detailed Demo Steps Additional Reading 14 15 18

8-14

Programming in C# with Microsoft Visual Studio 2010

Question and Answers


What Is an Abstract Class?
Question: Can a method in an abstract class contain a default implementation? Answer: Yes. This is the big advantage of using an abstract class: common functionality can be abstracted into an abstract class so that code does not need to be duplicated. If a method in an abstract class is marked override or virtual, you can override the default functionality in a child class.

What Is an Abstract Method?


Question: Can an abstract method contain a default implementation? Answer: No. However, a concrete method in an abstract class can contain a default implementation.

Demonstration: Creating an Abstract Class


Question: Can you combine abstract and nonabstract (concrete) methods in an abstract class? Answer: Yes. You can use any combination of abstract and concrete methods in an abstract class.

Inheriting from Classes and Implementing Interfaces

8-15

Detailed Demo Steps


Demonstration: Creating an Abstract Class Demonstration Steps
1. Open Visual Studio 2010: Click Start, point to All Programs, click Microsoft Visual Studio 2010, and then click Microsoft Visual Studio 2010. 2. Open the Module 8, Demo3 starter solution: a. b. 3. In Visual Studio, on the File menu, point to Open, and then click Project/Solution. Move to the E:\Demofiles\Mod8\Demo3\Starter\CreatingAnAbstractClassDemo folder, and then double-click CreatingAnAbstractClassDemo.sln.

Add a Television abstract class to the Program.cs file: a. b. In Solution Explorer, double-click Program.cs. Add the code in the following code example to the file.
abstract class Television { }

4.

Add a public TurnOn method to the class. The method should write a message to the console indicating that the television is on. Your code should resemble the following code example.
abstract class Television { public void TurnOn() { Console.WriteLine(Television on.); } }

5.

Add a public TurnOff method to the class. The method should write a message to the console indicating that the television is off. Your code should resemble the following code example.
abstract class Television { public void TurnOn() { Console.WriteLine(Television on.); } public void TurnOff() { Console.WriteLine(Television off.); } }

6.

Add a public abstract IncreaseVolume method to the class. Your code should resemble the following code example.

8-16

Programming in C# with Microsoft Visual Studio 2010

abstract class Television { public void TurnOn() { Console.WriteLine(Television on.); } public void TurnOff() { Console.WriteLine(Television off.); } public abstract void IncreaseVolume(); }

7.

Add a public abstract DecreaseVolume method to the class. Your code should resemble the following code example.
abstract class Television { public void TurnOn() { Console.WriteLine(Television on.); } public void TurnOff() { Console.WriteLine(Television off.); } public abstract void IncreaseVolume(); public abstract void DecreaseVolume(); }

8.

Add to the Program.cs file a WidescreenTV class that inherits from the abstract Television class: Add the code in the following code example to the file.
class WidescreenTV : Television { }

9.

Override the IncreaseVolume method. The method should write a message to the screen indicating that the volume has increased on the widescreen television. Your code should resemble the following code example.
class WidescreenTV : Television { public override void IncreaseVolume() { Console.WriteLine(Volume increased (WidescreenTV).); } }

10. Override the DecreaseVolume method. The method should write a message to the screen indicating that the volume has decreased on the widescreen television. Your code should resemble the following code example.
class WidescreenTV : Television { public override void IncreaseVolume() {

Inheriting from Classes and Implementing Interfaces

8-17

Console.WriteLine(Volume increased (WidescreenTV).); } public override void DecreaseVolume() { Console.WriteLine(Volume decreased (WidescreenTV).); } }

11. Add to the Program.cs file a TV class that inherits from the abstract Television class: Add the code in the following code example to the file:
class TV : Television { }

12. Override the IncreaseVolume method. The method should write a message to the screen indicating that the volume has increased on the television. Your code should resemble the following code example.
class TV : Television { public override void IncreaseVolume() { Console.WriteLine(Volume increased (TV).); } }

13. Override the DecreaseVolume method. The method should write a message to the screen indicating that the volume has increased on the television. Your code should resemble the following code example.
class TV : Television { public override void IncreaseVolume() { Console.WriteLine(Volume increased (TV).); } public override void DecreaseVolume() { Console.WriteLine(Volume decreased (TV).); } }

14. Uncomment the code in the Program class. 15. Run the application: On the Debug menu, click Start Without Debugging.

8-18

Programming in C# with Microsoft Visual Studio 2010

Additional Reading
What Is an Abstract Class?
For more information about the abstract modifier, see the abstract (C# Reference) page at http://go.microsoft.com/fwlink/?LinkId=192940.

What Is an Abstract Method?


For more information about abstract and sealed class members, see the Abstract and Sealed Classes and Class Members (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192939.

Inheriting from Classes and Implementing Interfaces

8-19

Module Review and Takeaways


Review Questions
1. What is the role of the object class in the .NET Framework? Answer: The object class is the ultimate base class of all types, including reference and value types. 2. What is the difference between implicit and explicit implementation of an interface? Answer: Explicit implementation removes ambiguity by specifically stating which interface a method is implementing. 3. What are the advantages of using an abstract class over an interface? Answer: An abstract class can contain default implementations of methods, whereas an interface can never contain any implementation.

Best Practices Related to Inheritance


Supplement or modify the following best practices for your own work situations: Create an inheritance hierarchy where appropriate to reduce code duplication. Where appropriate, mark methods as virtual to enable child classes to override them. Where appropriate, mark methods as sealed to prevent child classes from overriding them. Where appropriate, mark classes as sealed to prevent classes from inheriting from them.

Best Practices Related to Interfaces


Supplement or modify the following best practices for your own work situations: Use interfaces wherever possible as a contract that specifies what methods a class will expose. Prefix an interface with an uppercase I. IImplement interfaces explicitly wherever possible.

Best Practices Related to Abstract Classes


Supplement or modify the following best practices for your own work situations: Use abstract classes to abstract common functionality and reduce code duplication. UsUse abstract methods to guarantee that an inheriting class overrides a method.

8-20

Programming in C# with Microsoft Visual Studio 2010

Lab Review Questions and Answers


1. What steps are required to implement an interface? Answer: The class must inherit from the interface and provide an implementation of all methods that the interface defines. 2. How do you implement an abstract class? Answer: You use the abstract modifier and develop the class in the same manner as other classes. You can add abstract methods that have no implementation, but must be implemented instead by any classes that inherit from the abstract class.

Managing the Lifetime of Objects and Controlling Resources

9-1

Module 9
Managing the Lifetime of Objects and Controlling Resources
Contents:
Lesson 1: Introduction to Garbage Collection Lesson 2: Managing Resources Module Review and Takeaways Lab Review Questions and Answers 2 7 12 13

9-2

Programming in C# with Microsoft Visual Studio 2010

Lesson 1

Introduction to Garbage Collection


Contents:
Question and Answers Detailed Demo Steps Additional Reading 3 4 6

Managing the Lifetime of Objects and Controlling Resources

9-3

Question and Answers


The Object Life Cycle
Question: How can you control the creation phase for an object? Answer: You add a constructor to the class.

Managed Resources in the .NET Framework


Question: Is the stack a first in, first out (FIFO), LIFO, first in, last out (FILO), or random access memory store? Answer: The stack is a LIFO structure.

How Does the Garbage Collector Work?


Question: What is the purpose of the freachable queue? Answer: The freachable queue contains pointers to objects that are waiting for finalization.

Defining a Destructor
Question: Can you add a destructor to a struct? Answer: No. You can only add a destructor to a class.

The GC Class
Question: How can you inform the runtime that you need to allocate a large block of unmanaged memory? Answer: You can use the AddMemoryPressure method of the GC class.

Demonstration: Implementing a Destructor


Question: How can you delay execution of the current thread until all objects in the finalization queue are finalized? Answer: You can use the WaitForPendingFinalizers method of the GC class.

9-4

Programming in C# with Microsoft Visual Studio 2010

Detailed Demo Steps


Demonstration: Implementing a Destructor Demonstration Steps
Start the 10266A-GEN-DEV virtual machine, and then log on by using the following credentials: User name: Student Password: Pa$$w0rd 1. Start Microsoft Visual Studio 2010: Click Start, point to All Programs, click Microsoft Visual Studio 2010, and then click Microsoft Visual Studio 2010. 2. Open the Module 9, Demo1 starter solution: a. b. 3. On the File menu, point to Open, and then click Project/Solution. Move to the E:\Demofiles\Mod9\Demo1\Starter\Destructor Demo folder, and then double-click Destructor Demo.sln.

In the Employee.cs file, add a destructor to the Employee class. The destructor should write the current salary to the SalaryDetails.txt file: a. b. In Solution Explorer, double-click Employee.cs. the code in the following code example to the file.
~Employee() { File.WriteAllText(SalaryDetails.txt, salary.ToString()); Console.WriteLine(Employee finalized: {0}, name); }

4. 5.

Walk the students through the other code in the Employee class. Highlight the code that reads the current salary from a text file. Show the students the code in the Program.cs file. Highlight that each employee is given a pay rise and then the object reference is removed. Explain that this will make the object available for garbage collection and that the destructor will write the updated salary back to the file. Run the application: On the Debug menu, click Start Without Debugging.

6.

7.

Point out that all of the employees are paid the same amount; the pay rises do not reflect the update made to the text file by the destructor. Remind students that the garbage collector only runs when it needs to, and this program does not create enough objects or use enough memory to cause a collection. In the Program.cs file, uncomment the call to the AddMemoryPressure method. Explain that this makes the garbage collector free as much memory as possible ready for a large allocation of unmanaged memory. Run the application: On the Debug menu, click Start Without Debugging.

8.

9.

Managing the Lifetime of Objects and Controlling Resources

9-5

10. Explain that the results have not changedalthough the application now requires more memory, the application runs faster than the garbage collector finalizes the objects. 11. In the Program.cs file, uncomment the call to the WaitForPendingFinalizers method. 12. Run the application: On the Debug menu, click Start Without Debugging.

13. Highlight that the application now works as expected, because the application halts to wait for the finalizer to update the text file before continuing.

9-6

Programming in C# with Microsoft Visual Studio 2010

Additional Reading
Managed Resources in the .NET Framework
For more information about automatic memory management, see the 3.9 Automatic memory management page at http://go.microsoft.com/fwlink/?LinkId=192943.

Defining a Destructor
For more information about destructors, see the Destructors (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192944.

The GC Class
For more information about the GC class, see the GC Members page at http://go.microsoft.com/fwlink/?LinkId=192945.

Managing the Lifetime of Objects and Controlling Resources

9-7

Lesson 2

Managing Resources
Contents:
Question and Answers Detailed Demo Steps Additional Reading 8 9 11

9-8

Programming in C# with Microsoft Visual Studio 2010

Question and Answers


Why Manage Resources in a Managed Environment?
Question: What types of resources may need to be managed correctly? Answer: Resources that are valuable, such as database connections, file operations, or objects that cache data in memory.

What Is the Dispose Pattern?


Question: What exception should you throw in your class if you attempt to use it after it has been disposed of? Answer: You should throw an ObjectDisposedException exception.

Managing Resources in Your Applications


Question: If you do not dispose of an object when you have finished with it, will the runtime call the Dispose method automatically? Answer: No. The runtime will not call the Dispose method; you must always add the code to call the Dispose method yourself.

Demonstration: Using the Dispose Pattern


Question: What is the preferred construct for managing resources in an application? Answer: Implement the dispose pattern and use a using statement to manage resources.

Managing the Lifetime of Objects and Controlling Resources

9-9

Detailed Demo Steps


Demonstration: Using the Dispose Pattern Demonstration Steps
1. Start Visual Studio 2010: a. 2. Click Start, point to All Programs, click Microsoft Visual Studio 2010, and then click Microsoft Visual Studio 2010.

Open the Module 9, Demo1 starter solution: a. b. On the File menu, point to Open, and then click Project/Solution. Move to the E:\Demofiles\Mod9\Demo2\Starter\Dispose Demo folder, and then double-click Dispose Demo.sln.

3.

Modify the Employee class to implement the IDisposable interface. The code should follow best practices. Explain to students that although the call to GC.SuppressFinalize in the Dispose method is unnecessary at present, it is still worth including it in case a finalizer is added to the Employee class later. Your completed code should resemble the following code example.
class Employee : IDisposable { bool isDisposed = false; string name; public Employee(string Name) { name = Name; } public void PaySalary() { if (!isDisposed) { Console.WriteLine("Employee {0} paid.", name); } else { throw new ObjectDisposedException("Employee already disposed."); } } public void Dispose() { Dispose(true); } protected virtual void Dispose(bool IsDisposing) { if (IsDisposing) { isDisposed = true; Console.WriteLine("Employee object disposed."); } GC.SuppressFinalize(this); }

9-10

Programming in C# with Microsoft Visual Studio 2010

4. 5.

Walk students through the Program class. Show them the using construct and the inline code. Explain that the using statement is exception safe and the inline code is not exception safe. Run the application: On the Debug menu, click Start Without Debugging.

6. 7.

When the application pauses, press ENTER. Point out the unhandled exception. Explain that the using statement prevented these exceptions.

Managing the Lifetime of Objects and Controlling Resources

9-11

Additional Reading
What Is the Dispose Pattern?
For more information about the Dispose method, see the Implementing a Dispose Method page at http://go.microsoft.com/fwlink/?LinkId=192946.

Demonstration: Using the Dispose Pattern


For more information about the using statement, see the using Statement (C# Reference) page at http://go.microsoft.com/fwlink/?LinkId=192947.

9-12

Programming in C# with Microsoft Visual Studio 2010

Module Review and Takeaways


Review Questions
1. What methods are defined in the IDisposable interface? Answer: The IDisposable interface includes a Dispose method that takes no parameters and returns nothing. 2. Where would an instance of the System.String class be stored: on the heap or on the stack? Answer: The String class is a class. Therefore, it is a reference type that is stored on the heap. 3. Should you add a destructor to every class you develop? Answer: No. You should only add a destructor where necessary. Adding a destructor to a class significantly lengthens the time for the memory used by an object to be reclaimed (even if the destructor does nothing).

Best Practices Related to Disposing of Unmanaged Objects


Supplement or modify the following best practices for your own work situations: You should implement the dispose pattern whenever your code uses unmanaged resources. You should use a using statement to ensure disposal of objects wherever possible. Where a using statement is not appropriate, you should ensure exception-safe disposal of objects by using a try/finally block; you should release resources in the finally block.

Managing the Lifetime of Objects and Controlling Resources

9-13

Lab Review Questions and Answers


1. How do you alias a Dispose method? Answer: You implement the IDisposable interface explicitly and then add a public method with an appropriate name to your class, which itself calls the Dispose method. 2. What is the syntax of the using statement? Answer: You use the using keyword, followed by a variable declaration in brackets. You then use braces to define the block of code that uses the defined variable.

Encapsulating Data and Defining Overloaded Operators

10-1

Module 10
Encapsulating Data and Defining Overloaded Operators
Contents:
Lesson 1: Creating and Using Properties Lesson 2: Creating and Using Indexers Lesson 3: Overloading Operators Module Review and Takeaways Lab Review Questions and Answers 2 8 12 16 17

10-2

Programming in C# with Microsoft Visual Studio 2010

Lesson 1

Creating and Using Properties


Contents:
Question and Answers Detailed Demo Steps Additional Reading 3 5 7

Encapsulating Data and Defining Overloaded Operators

10-3

Question and Answers


What Is a Property?
Question: How does the behavior of a method differ from a property? Answer: A method can take a set of parameters of various types, and it performs a function. A property is assigned a single value and is intended to set a value, not perform a function. A property may perform some functionality as a side effect of the assignment, but this should not be the purpose of the property.

Defining a Property
Question: How can you enable write access to a property to other types in the same assembly, but read access to a property from a class in any assembly? Answer: Declare a public property, but mark the set accessor internal.

Automatic Properties
Question: What is the benefit of using an automatic property compared to exposing a public field? Answer: An automatic property is simply another property to consuming applications. If you must change your type in the future, and you must change a field to a property, any consuming application must be recompiled; however, if you simply change from an automatic property to a manually implemented property, the change is invisible to the consuming application.

Instantiating an Object by Using Properties


Question: Why is it important to instantiate required properties to default values in the constructor? Answer: Object initializers do not require consuming code to set a specific set of fields. A consuming class may fail to set all of the required fields in the object initializer. This may cause errors when the object is used. Setting all required properties to default values in the constructor should avoid this problem.

Defining Properties in an Interface


Question: When should you add a property to an interface? Answer: You should add a property to an interface when it exposes data that is important for consuming classes to access and where the exposure of that property is crucial to the intended purpose of the interface.

Best Practices When Defining and Using Properties


Question: When would you add logic to a get accessor that performs functionality other than to return the data?

10-4

Programming in C# with Microsoft Visual Studio 2010

Answer: If you are writing code for a secure environment where you must log access to the data.

Demonstration: Using Properties


Question: If you set a property in a constructor, and you use named properties to set the same property when you instantiate the object, which takes precedence: the value from the constructor or the named property? Answer: The named property. The constructor runs first, and then the named properties are applied; therefore, they overwrite any properties set in the constructor.

Encapsulating Data and Defining Overloaded Operators

10-5

Detailed Demo Steps


Demonstration: Using Properties Demonstration Steps
1. Start Microsoft Visual Studio 2010: Click Start, point to All Programs, click Microsoft Visual Studio 2010, and then click Microsoft Visual Studio 2010. 2. Open the Module 10, Demo1 starter solution: a. b. 3. On the File menu, point to Open, and then click Project/Solution. Move to the E:\Demofiles\Mod10\Demo1\Starter\UsingPropertiesDemo folder, and then double-click UsingPropertiesDemo.sln.

Open the Employee.cs file, and then review the Employee class. Highlight the publicly exposed fields. Also highlight the constructor that sets the Name field based on the parameter and the Salary and Department fields to default values: In Solution Explorer, double-click Employee.cs, and then explain the contents of the class.

4.

Convert the Name field to a property by using automatic properties: Modify the following line of code.
public string Name;

Change it to the following line of code.


public string Name { get; set; }

5.

Convert the Department field to a property by using automatic properties: Modify the following line of code.
public string Department;

Change it to the following line of code.


public string Department { get; set; }

6.

Convert the public Salary field to a private field and rename it salary: Modify the following line of code.
public int Salary;

Change it to the following line of code.


private int salary;

7. 8.

Uncomment the commented Salary property, and then explain how it ensures that an employee can never have a negative salary. Open the Program.cs file, and then review the Employee object.

10-6

Programming in C# with Microsoft Visual Studio 2010

In Solution Explorer, double-click Program.cs, and then explain the contents of the object. 9. Uncomment all of the code up to and including the first occurrence of the following code.
Console.ReadLine();

10. Describe the code that you have just uncommented: a. b. Explain how the julie object is created by using the constructor, and explain that the properties are subsequently set by using the dot notation. Explain how the james object is created by using named properties. Emphasize that these named properties are set after the constructor is run, so they take precedence over the default values set by the constructor.

11. Uncomment the remaining code in the file. 12. Describe the code that you have just uncommented: Explain that the code attempts to set James salary to a negative value. Remind students that the property prevented negative values. 13. Run the application: On the Debug menu, click Start Without Debugging. 14. When the application pauses, highlight that the application has worked as expected, and the two employees details are displayed correctly, and then press ENTER. 15. When the application pauses, highlight that the application has worked as expected, and James salary has been set to 0 instead of a negative value, and then press ENTER. 16. Close Visual Studio: In Visual Studio, on the File menu, click Exit.

Encapsulating Data and Defining Overloaded Operators

10-7

Additional Reading
What Is a Property?
For more information about properties, see the Properties (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192948.

Defining a Property
For more information about using properties, see the Using Properties (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192949.

Defining Properties in an Interface


For more information about defining properties in an interface, see the Interface Properties (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192950.

Best Practices When Defining and Using Properties


For more information about choosing between properties and methods, see the Choosing Between Properties and Methods page at http://go.microsoft.com/fwlink/?LinkId=192951.

10-8

Programming in C# with Microsoft Visual Studio 2010

Lesson 2

Creating and Using Indexers


Contents:
Question and Answers Detailed Demo Steps Additional Reading 9 10 11

Encapsulating Data and Defining Overloaded Operators

10-9

Question and Answers


What Is an Indexer?
Question: When may you want to add an indexer to a type? Answer: When the type exposes a set of data to which you want to enable access to individual members.

Creating an Indexer
Question: What information should you use as parameters for an indexer? Answer: You should only use parameters that are necessary to locate an individual data member in the dataset. You should not use parameters to manipulate data.

Comparing Indexers and Arrays


Question: Should you use an indexer or an array if you must pass a value to a method by reference? Answer: You must use an array; you cannot use an indexer as a ref parameter.

Defining an Indexer in an Interface


Question: How can you use interfaces to add more than one indexer that takes the same parameters to a class? Answer: You can explicitly implement several interfaces that include indexers. However, you cannot add any other indexers to the class if you take this approach.

Demonstration: Creating and Using an Indexer


Question: Can you develop more than one indexer with the same set of parameters? Answer: No. You cannot define several indexers with the same set of parameters. Indexers are always named by using the this keyword. You can create methods instead if you need to perform several operations with the same parameters.

10-10

Programming in C# with Microsoft Visual Studio 2010

Detailed Demo Steps


Demonstration: Creating and Using an Indexer Demonstration Steps
1. Start Visual Studio: Click Start, point to All Programs, click Microsoft Visual Studio 2010, and then click Microsoft Visual Studio 2010. 2. Open the Module 10, Demo2 starter solution: a. b. On the File menu, point to Open, and then click Project/Solution. Move to the E:\Demofiles\Mod10\Demo2\Starter\CreatingAndUsingAnIndexerDemo folder, and then double-click CreatingAndUsingAnIndexerDemo.sln.

3.

Open the EmployeeDatabase.cs file, and then review the EmployeeDatabase class: a. b. c. In Solution Explorer, double-click EmployeeDatabase.cs, and then describe the class. Highlight that the class stores an array of Employee objects. Highlight the AddToDatabase method, and then explain how it adds Employee objects to the array and increments a pointer to the top of the array.

4.

Uncomment the indexer that returns an Employee object. Explain how the indexer takes a string parameter called Name and iterates through each employee in the array until it finds one with a matching Name property. It then returns that value. If it does not find a match after iterating over the entire array, it returns null. Open the Program.cs file, and then describe the class: In the Program.cs file, uncomment the commented code, and then explain how this code uses the indexer to retrieve Employee instances by specifying the employee name. Remind students that this would not be possible with an array because you can only access an array by index. In Solution Explorer, double-click Program.cs, and then explain how the class creates an instance of the EmployeeDatabase class and then adds several Employee objects to the class.

5. 6.

7.

Run the application: On the Debug menu, click Start Without Debugging.

8. 9.

Highlight that the application runs as expected, and the details of the two employees retrieved from the database are displayed correctly, and then press ENTER. Close Visual Studio: In Visual Studio, on the File menu, click Exit.

Encapsulating Data and Defining Overloaded Operators

10-11

Additional Reading
What Is an Indexer?
For more information about the comparison between properties and indexers, see the Comparison Between Properties and Indexers (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192952.

Creating an Indexer
For more information about using indexers, see the Using Indexers (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192953.

10-12

Programming in C# with Microsoft Visual Studio 2010

Lesson 3

Overloading Operators
Contents:
Question and Answers Detailed Demo Steps Additional Reading 13 14 15

Encapsulating Data and Defining Overloaded Operators

10-13

Question and Answers


What Is Operator Overloading?
Question: If you overload the + operator in a type, does the compiler automatically generate an equivalent operator? Answer: No. The compiler does not generate any operators for you.

Overloading an Operator
Question: Does the first operand of an overloaded operator have to be the containing type? Answer: No. At least one of the operands has to be the containing type, but there is no requirement for it to be the first operand.

Restrictions When Overloading Operators


Question: How can you change the multiplicity of an operator? Answer: You cannot change the multiplicity of an operator; instead, you should define a method to perform the operation.

Best Practices When Overloading Operators


Question: Why should you always return a new object rather than update one of the operands? Answer: There may be several references to the operand. Updating the operand may have an unexpected effect on other instances.

Implementing and Using Conversion Operators


Question: When should you use an explicit conversion? Answer: You should use an explicit conversion when it is a narrowing conversion that may lead to loss of data or where there is a risk of an exception.

Demonstration: Overloading an Operator


Question: When can you use the += syntax to abbreviate an addition operation? Answer: You can use the += syntax when the first operand and the return type of the addition operation are the same type.

10-14

Programming in C# with Microsoft Visual Studio 2010

Detailed Demo Steps


Demonstration: Overloading an Operator Demonstration Steps
1. Start Visual Studio: Click Start, point to All Programs, click Microsoft Visual Studio 2010, and then click Microsoft Visual Studio 2010. 2. Open the Module 10, Demo3 starter solution: a. b. 3. On the File menu, point to Open, and then click Project/Solution. Move to the E:\Demofiles\Mod10\Demo3\Starter\OverloadingAnOperator folder, and then double-click OverloadingAnOperator.sln.

Open the EmployeeDatabase.cs file, and then review the EmployeeDatabase class: a. b. In Solution Explorer, double-click EmployeeDatabase.cs, and then describe the class. Highlight that the class stores an array of Employee objects and is the same as in the previous demonstration.

4.

Uncomment the + operator that returns an EmployeeDatabase object. Explain how the + operator takes an EmployeeDatabase object and an Employee object as parameters, adds the Employee object to the database, and then returns a reference to the database. Open the Program.cs file, and then describe the class: In the Program.cs file, uncomment the commented code, and then explain how this code adds several Employee objects to the database by using both the + syntax and the += syntax. In Solution Explorer, double-click Program.cs, and then explain how the class creates an instance of the EmployeeDatabase class and then adds several Employee objects to the class.

5. 6.

7.

Run the application: On the Debug menu, click Start Without Debugging.

8. 9.

Highlight that the application runs as expected, and the details of the two employees retrieved from the database are displayed correctly, and then press ENTER. Close Visual Studio: In Visual Studio, on the File menu, click Exit.

Encapsulating Data and Defining Overloaded Operators

10-15

Additional Reading
Restrictions When Overloading Operators
For more information about using the Equals method, see the Object.Equals Method (Object) page at http://go.microsoft.com/fwlink/?LinkId=192954.

10-16

Programming in C# with Microsoft Visual Studio 2010

Module Review and Takeaways


Review Questions
1. If you are developing a new type and must expose data, how can you expose the data as a property with minimal extra effort? Answer: You can use an automatic property. An automatic property is quick to use and helps to ensure forward-compatibility if your logic must change in the future. 2. You must develop an application to represent a set of data. You must expose individual members of the data to consuming classes. How can you expose individual members in a dataset to consuming classes, and are there any disadvantages to the approach? Answer: You can use an indexer to expose individual items in the dataset. The downside of using an indexer is that you cannot use an indexer as a ref or out parameter in your code. 3. You have overloaded the == operator in a type you are developing. As required by the compiler, and to comply with best practices, you are also going to implement the != operator. Should you implement the != operator from scratch, or should you use the == operator that you have already defined and negate the result? Answer: You should implement the operator from scratch. Checking whether an object is not equal can often be performed more efficiently than negating the result of checking whether an object is equal, and you should aim to write the most efficient code you can.

Best Practices Related to Properties


Supplement or modify the following best practices for your own work situations: Use properties only when a property is appropriate, but do not expose data unnecessarily. Use automatic properties instead of making a field public unless there is a very good reason not to.

Best Practices Related to Indexers


Supplement or modify the following best practices for your own work situations: Use an indexer to access a data member that is part of a set. An indexer is not a method: if you are writing too much code in an indexer, consider whether it would be better implemented as a method.

Best Practices Related to Operators


Supplement or modify the following best practices for your own work situations: Implement symmetric operators for commutable operations. Do not modify the value of operands in an operator. Define only meaningful operators.

Encapsulating Data and Defining Overloaded Operators

10-17

Lab Review Questions and Answers


Lab A: 1. What is the syntax for declaring a property in an interface? Answer: You specify the type and the property name, followed by the get and/or set accessors in braces with a semicolon after each, as in the following example: string Name { get; set; }. 2. What is the significant difference between automatic properties and nonautomatic properties? Answer: With automatic properties, you are required to add both get and set accessors. With nonautomatic properties, you can choose to expose get or set or both. 3. What happens if you attempt to write to a property that exposes only a get accessor? Answer: Your code will not compile. Lab B: 1. Can you overload an indexer in a child class? Answer: Yes. Overloading an indexer in a child class is one of the advantages of an indexer compared to an array. 2. What are some of the advantages of using an indexer in your class? Answer: You can access individual data members by using nonnumeric subscripts. You can provide several overloads that take different subscripts (type) to access data by using different types of parameter. 3. When can it be inappropriate to use an indexer in your class? Answer: If you must use the indexer as a ref or out parameter to a method. You can use an array as a ref or out parameter, but you cannot use an indexer. Lab C: 1. Can you declare an operator that is not static? Answer: No. In Visual C#, operators are always static. They do not operate on an instance of an object; you must specify all of the operands in your code. 2. Can you change the multiplicity of an operator? Answer: No. The multiplicity of the operators in Visual C# is fixed. If you must perform functionality that requires a change to the multiplicity of an operator, you should declare a method instead. 3. What must a binary operator do to support compound assignment statements? Answer: The return type and the first operand must be the same.

Decoupling Methods and Handling Events

11-1

Module 11
Decoupling Methods and Handling Events
Contents:
Lesson 1: Declaring and Using Delegates Lesson 2: Using Lambda Expressions Lesson 3: Handling Events Module Review and Takeaways Lab Review Questions and Answers 2 5 8 12 14

11-2

Programming in C# with Microsoft Visual Studio 2010

Lesson 1

Declaring and Using Delegates


Contents:
Question and Answers Additional Reading 3 4

Decoupling Methods and Handling Events

11-3

Question and Answers


Why Decouple an Operation from a Method?
Question: If you develop a class library and want to enable developers who write consuming applications to run code after an asynchronous method call completes, how can you provide this functionality? Answer: You can expose a delegate in your class library that other developers can add handlers to. You then invoke the delegate after the logic in your method completes.

Defining a Delegate
Question: Which of the following are valid scopes to define a delegate: the namespace scope, the class scope, or the method scope? Answer: You can define a delegate at either the namespace or the class scope. You cannot define a delegate in a method.

Invoking a Delegate
Question: Why should you always check that a delegate is not null before you invoke it? Answer: If a delegate does not reference any methods, it will return null. If you attempt to invoke a null delegate, your application will throw a NullReferenceException exception.

Defining Anonymous Methods


Question: If you specify parameters for an anonymous method, do you need to specify the types of those parameters? Answer: Yes. Anonymous methods infer the return type, but not the type of parameters. However, you can omit the parameter list if you do not need to access any of the parameter values in the method.

11-4

Programming in C# with Microsoft Visual Studio 2010

Additional Reading
Defining a Delegate
For more information about delegates, see the Delegates (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192955.

Invoking a Delegate
For more information about asynchronous programming, see the Asynchronous Programming Overview page at http://go.microsoft.com/fwlink/?LinkId=192956.

Defining Anonymous Methods


For more information about anonymous methods, see the Anonymous Methods (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192961.

Decoupling Methods and Handling Events

11-5

Lesson 2

Using Lambda Expressions


Contents:
Question and Answers Additional Reading 6 7

11-6

Programming in C# with Microsoft Visual Studio 2010

Question and Answers


What Is a Lambda Expression?
Question: Can you define a lambda expression without using a delegate to reference the expression? Answer: No. If you could, you would not have any way to call the expression.

Defining Lambda Expressions


Question: When can you omit the parentheses that surround the parameters in a lambda expression? Answer: When there is exactly one parameter.

Variable Scope in Lambda Expressions


Question: If you reference an open database connection in a lambda expression, which would normally go out of scope at the end of the method that defines the expression, what happens to the database connection when the method completes? Answer: The database connection remains open in case the lambda expression is invoked. The resource is not released until all references to the lambda expression have been removed (normally when the delegate goes out of scope).

Decoupling Methods and Handling Events

11-7

Additional Reading
Defining Lambda Expressions
For more information about lambda expressions, see the Lambda Expressions (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192957.

11-8

Programming in C# with Microsoft Visual Studio 2010

Lesson 3

Handling Events
Contents:
Question and Answers Detailed Demo Steps Additional Reading 9 10 11

Decoupling Methods and Handling Events

11-9

Question and Answers


What Is an Event?
Question: What is the difference between a publicly exposed instance of a delegate and a publicly exposed event? Answer: You can invoke a delegate from any consuming type, whereas you can only invoke an event in the containing class or a derivative of it.

Defining an Event
Question: What is the result of defining a public event based on a private delegate? Answer: The code will not compile; it is an error for an event to be more visible than the delegate type that it is based on.

Using Events
Question: Can consuming classes raise an event? Answer: No. An event can be raised only by the containing class or a class that inherits from that class.

Best Practices for Using Events


Question: What is the naming convention for methods that encapsulate the logic associated with raising an event? Answer: The method should be named to match the event name, but prefixed with the word On.

Using Events in Graphical Applications


Question: Can you add code to the DoWork event handler to update the user interface directly? Answer: No. The DoWork event handler does not run on the UI thread, so it cannot update the user interface. Instead, it can marshal data back to the UI thread and raise an event on the UI thread to update the user interface.

Demonstration: Using Events


Question: Why should you use the protected modifier instead of the public modifier as the access modifier for an On method? Answer: An On method is intended to raise the event. An event should only be raised by the containing class of a derivative of that class. The protected access modifier grants access to the containing class and to classes that derive from it. If you use the public access modifier, any class that consumes the type could call the On method and raise the event.

11-10

Programming in C# with Microsoft Visual Studio 2010

Detailed Demo Steps


Demonstration: Using Events Demonstration Steps
1. 2. 3. 4. 5. 6. Log on to the 10266A-GEN-DEV virtual machine as Student with the password Pa$$w0rd. Start Microsoft Visual Studio 2010. Open the Module 11, Demo1 starter solution. Open the Heartbeat.cs file, and then review the Heartbeat class. Uncomment the HeartbeatEventArgs class. This class inherits from the EventArgs class and defines a read-only property for the heartbeat count. Uncomment the code that creates a new delegate named BeatDelegate. You will use this delegate for an event to inform consuming classes each time the application increments the heartbeat counter. Uncomment the code that defines an event named Beat that is based on the BeatDelegate delegate. Your class will raise this event each time the heartbeat count is incremented. Uncomment the OnBeat method. This method includes logic to check that the Beat event is not null (which would indicate that the event had no subscribers) before raising the event. This is best practice, and this method can be overridden in child classes. Uncomment the code in the Start method that raises the Beat event by using the OnBeat method. You use the this keyword as the first parameter and create a new instance of the HeartbeatEventArgs class by using the current count as the second parameter.

7. 8.

9.

10. Open the MainWindow.xaml.cs file, and then review the event handlers for the Click events. 11. Uncomment the code in the button1_Click method that adds an event handler for the Beat event of the beat object. 12. Uncomment the beat_Beat method. This method handles the Beat event by displaying a message box each time that the event is raised. Note the use of the property from the custom event arguments class. 13. Run the application. 14. Click Start. 15. Verify that the application works correctly. Highlight the message boxes when they appear (they should appear every three seconds). 16. Close the application. 17. Close Visual Studio.

Decoupling Methods and Handling Events

11-11

Additional Reading
Defining an Event
For more information about events, see the Events (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192958.

Using Events
For more information about how to publish events, see the How to: Publish Events that Conform to .NET Framework Guidelines (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192959. For more information about how to hook up events, see the How to: Hook Up Events By Using IntelliSense (C#) page at http://go.microsoft.com/fwlink/?LinkId=192962.

Using Events in Graphical Applications


For more information about how to run an operation in the background, see the How to: Run an Operation in the Background page at http://go.microsoft.com/fwlink/?LinkId=192960.

11-12

Programming in C# with Microsoft Visual Studio 2010

Module Review and Takeaways


Review Questions
1. When might it be inappropriate to use a lambda expression? Answer: There are several answers; this question can be a good topic for discussion if time permits. One important answer is that it is inappropriate if you must write the same lambda expression on more than one occasionif this is the case, you should avoid code duplication, create a named method, and use the named method on each occasion. In addition, if the lambda expression becomes very long, it may be more readable and otherwise clearer to create a named method; generally, lambda expressions should be kept relatively short (although they may take a long time to run). 2. How can you invoke a method asynchronously if it only natively supports being called synchronously? Answer: You can create a delegate with a signature that matches the method and then add the method as a handler for the delegate. The delegate type includes BeginInvoke and EndInvoke methods and other members that you can use to invoke any synchronous method asynchronously. 3. Can lambda expressions use variables declared outside the lambda expression? Answer: Yes. However, doing so will often affect the life cycle of the variable. For example, a variable defined in a method that would otherwise have gone out of scope will be persisted until the lambda expression goes out of scope if used in the lambda expression. This can unexpectedly increase the lifespan of a variable and potentially resource usage as a consequence.

Best Practices Related to Using Delegates


Supplement or modify the following best practices for your own work situations: Use the delegate types defined in the .NET Framework instead of developing custom delegate types wherever possible. Use delegates to invoke synchronous methods asynchronously where appropriate; however, you should not omit asynchronous methods from a type where you can implement the asynchronous version of a method more efficiently than using the delegate syntax.

Best Practices Related to Using Lambda Expressions


Supplement or modify the following best practices for your own work situations: Only use a lambda expression if you use the method only once. If you are writing duplicate lambda expressions, you should normally use a named method instead. Do not change an object's state in a lambda expression. Wherever possible, you should write lambda expressions that do not have side effects. Avoid referencing variables defined outside the scope of the lambda expression.

Best Practices Related to Using Events


Supplement or modify the following best practices for your own work situations: Use the standard event signature. Use a protected virtual method to raise an event.

Decoupling Methods and Handling Events

11-13

Do not pass null as a parameter when you raise an event.

11-14

Programming in C# with Microsoft Visual Studio 2010

Lab Review Questions and Answers


1. If you define a delegate for an event, when should you use the EventArgs class? Answer: You should use the EventArgs class only if you are sure that neither the current version nor any future version will need to pass any data as an argument when the event is raised. If there is a chance that you may need to pass an argument in the future, you should use a class that inherits from the EventArgs class instead. 2. What are the advantages of defining an On method to raise an event? Answer: When you define an On method, you reduce code duplication; for example, code that you run every time you raise an event needs to be written only once, and you then raise the event by using the method. In addition to reducing code duplication, an On method ensures that any classes that derive from your class can modify the behavior when the class raises the event if the requirements change. 3. What is the primary difference between exposing an instance of a delegate and exposing an event? Answer: If you expose an instance of a delegate, consuming applications can both subscribe to the delegate and invoke the delegate. If you expose an event, consuming applications can subscribe to the event, but they cannot raise the event (invoke the handler). Only the containing class (or one that derives from it) can raise the event. 4. When you define a lambda expression, what are the rules for using type inference with input parameters? Answer: The types must be able to be inferred from the delegate that references the expression. If your lambda expression takes a different type (for example, where an implicit conversion between the delegate type and the required type exists), you cannot use type inference and must explicitly type the parameters. If you explicitly type a single parameter, you must explicitly type all of the parameters for that lambda expression. You cannot combine implicit and explicit type inference in a lambda expression.

Using Collections and Building Generic Types

12-1

Module 12
Using Collections and Building Generic Types
Contents:
Lesson 1: Using Collections Lesson 2: Creating and Using Generic Types Lesson 3: Defining Generic Interfaces and Understanding Variance Lesson 4: Using Generic Methods and Delegates Module Review and Takeaways Lab Review Questions and Answers 2 7 11 14 18 19

12-2

Programming in C# with Microsoft Visual Studio 2010

Lesson 1

Using Collections
Contents:
Question and Answers Detailed Demo Steps Additional Reading 3 5 6

Using Collections and Building Generic Types

12-3

Question and Answers


What Is a Collection?
Question: You are developing an application that maintains a rolling buffer of 10 readings taken by a device. Would you use an array or a collection to store the values? Answer: You would normally use an array. If you did not know the size of the collection, a collection may be more appropriate. However, the number of readings that you need to store an array is more efficient, in addition to being type-safe.

Using Collection Classes


Question: Are collections type-safe? Answer: No. Collections store items by using the System.Object type. When you retrieve an item from a collection, you must cast it to the correct type. The compiler cannot verify that your cast is correct at compile time; rather, at run time, your application will throw an InvalidCastException exception if you attempt an invalid cast.

Iterating Through a Collection


Question: When you use a foreach statement with a collection based on the SortedList type, in what order will the foreach statement return items from the collection? Answer: The foreach statement will order the items according to the key that is provided for each key and value pair in the collection.

Common Collection Classes


Question: When would you use a Hashtable collection? Answer: When you need to store a large number of items that include a key and value pair. You should not use a Hashtable collection for small collections because the overhead of maintaining the Hashtable collection will exceed the gains compared to other collection classes.

Using Collection Initializers


Question: Can you use a collection initializer with the Stack collection class? Answer: No. The Stack collection class exposes Push and Pop methods to add and remove items. To use a collection initializer, the class must expose an Add method.

Demonstration: Using Collections


Question: What is the advantage of using the SortedList class compared to using a multidimensional array? Answer: The SortedList class enables you to add items to the collection, and it automatically grows in size as you add more items. An array has a fixed size and will not grow when you reach the

12-4

Programming in C# with Microsoft Visual Studio 2010

maximum capacity. The SortedList class also enables you to retrieve items from the collection by specifying the key. Using an array, you must use a numeric index to access items in the array.

Using Collections and Building Generic Types

12-5

Detailed Demo Steps


Demonstration: Using Collections Demonstration Steps
1. 2. Log on to the 10266A-GEN-DEV virtual machine as Student with the password Pa$$word. Start Microsoft Visual Studio 2010: Click Start, point to All Programs, click Microsoft Visual Studio 2010, and then click Microsoft Visual Studio 2010. 3. Open the Module 12, Demo1 starter solution: On the File menu, point to Open, and then click Project/Solution. Move to the E:\Demofiles\Mod12\Demo1\Starter\UsingCollectionsDemo folder, and then double-click UsingCollectionsDemo.sln. 4. Open the Program.cs file, and then review the Program class: In Solution Explorer, double-click Program.cs, and then describe the Program class (which currently does nothing of any interest). 5. 6. 7. 8. 9. Uncomment the code that creates a new SortedList collection named people. Uncomment the code that adds a Person object named Richard to the people collection. Explain how this code uses an object initializer. Uncomment the code that creates a Person object named louisa. Uncomment the code that adds the louisa object to the people collection. Explain how this uses the Add method to add an existing item to an existing collection. Uncomment the code that retrieves a Person object from the people collection by using the name as an indexer. Highlight the cast from the object type to the Person type.

10. Uncomment the code that checks whether the personFromCollection field is null and, if it is not null, writes the information to the screen. 11. Uncomment the code that iterates through every item in the people collection. Run the application: On the Debug menu, click Start Without Debugging. 12. When the application pauses, highlight the data that is returned from the collection and displayed on the screen, and then press ENTER. 13. When the application pauses again, highlight that the details of two people are displayed on the screen, and then press ENTER. 14. Close the application. 15. Close Visual Studio: In Visual Studio, on the File menu, click Exit.

12-6

Programming in C# with Microsoft Visual Studio 2010

Additional Reading
Common Collection Classes
For more information about the common collection types, see the Commonly Used Collection Types page at http://go.microsoft.com/fwlink/?LinkId=192963.

Using Collection Initializers


For more information about collection initializers, see the Object and Collection Initializers (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192964.

Using Collections and Building Generic Types

12-7

Lesson 2

Creating and Using Generic Types


Contents:
Question and Answers Detailed Demo Steps Additional Reading 8 9 10

12-8

Programming in C# with Microsoft Visual Studio 2010

Question and Answers


What Are Generic Types?
Question: What are the benefits of using a generic class compared to a nongeneric class? Answer: The benefits of using a generic class include ensuring compile-time type safety and enabling you to omit casts in your applications.

Compiling Generic Types and Type Safety


Question: When the compiler compiles an application that uses a generic type, it generates a concrete version of the generic class. How can you call the concrete version in your application? Answer: You use the generic class. You can never directly call the compiler-generated class; you must call the generic class and the compiler will convert your method calls to use the concrete class when it compiles the application.

Defining a Custom Generic Type


Question: How can you instantiate a variable when you do not know the type and cannot be certain that the type exposes a constructor? Answer: You can use the default keyword to instantiate a variable.

Adding Constraints to Generic Types


Question: How can you ensure that, when an instance of a generic class is created, a reference type is used for the type parameter? Answer: The database connection remains open in case the lambda expression is invoked. The resource is not released until all references to the lambda expression have been removed (normally when the delegate goes out of scope).

Demonstration: Defining a Generic Type


Question: What happens if you attempt to use the wrong type when you call a method that uses a generic type? Answer: The code will not compile. The compiler ensures type safety when you use generic types.

Using Collections and Building Generic Types

12-9

Detailed Demo Steps


Demonstration: Defining a Generic Type Demonstration Steps
1. 2. 3. Start Visual Studio. Open the Module 12, Demo2 starter solution. Open the Printer.cs file, and then review the Printer class. The Printer class is a generic class that takes a single type parameter named DocumentType. The purpose of the class is to represent a printer that is capable of printing a specific type of document. 4. Uncomment the code that creates a new Queue<> object named printQueue by using the DocumentType type parameter to specify the type of the Queue object. This collection class stores items in a FIFO manner. Uncomment the AddDocumentToQueue method. This method uses the generic type parameter to define the types that can be used as a parameter. Uncomment the PrintDocuments method. This method removes items from the queue and calls the Print method on each item. Open the Program.cs file, and then review the Program class. The Program class currently creates three Report objects and three ReferenceGuide objects. The Report and ReferenceGuide classes both implement the IPrintable interface, but are not related in any other way. 8. 9. Uncomment the code that creates a new instance of the Printer class by specifying the Report type and adds three reports to the print queue. Uncomment the code that calls the PrintDocuments method on the reportPrinter object. This calls the method from the Printer class and removes each item from the print queue.

5. 6. 7.

10. Uncomment the code that creates a new instance of the Printer class by specifying the ReferenceGuide type and adds three reference guides to the print queue. 11. Uncomment the code that calls the PrintDocuments method on the referenceGuidePrinter object. This calls the method from the Printer class and removes each item from the print queue. 12. Run the application. 13. Close the application. 14. Close Visual Studio.

12-10

Programming in C# with Microsoft Visual Studio 2010

Additional Reading
What Are Generic Types?
For more information about generics, see the Generics (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192965.

Adding Constraints to Generic Types


For more information about constraints, see the Constraints on Type Parameters (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192966.

Using Collections and Building Generic Types

12-11

Lesson 3

Defining Generic Interfaces and Understanding Variance


Contents:
Question and Answers Additional Reading 12 13

12-12

Programming in C# with Microsoft Visual Studio 2010

Question and Answers


Defining Generic Interfaces
Question: How can you ensure that types that are used with a generic interface can be compared? Answer: Add a constraint by using the where keyword, which specifies that types that are used with the generic interface implement the IComparable interface.

What Is Invariance?
Question: When you define a generic interface, by default, is it invariant, contravariant, or covariant? Answer: By default, generic interfaces are invariant.

Defining and Implementing a Covariant Interface


Question: Can you use an out qualifier with a type parameter that is used as a parameter in a method call? Answer: No. You can only use the out qualifier with types that are used solely as return types.

Defining and Implementing a Contravariant Interface


Question: If a type is used for both input and output, can you mark the type with the in qualifier? Answer: No. You can only use the in qualifier with types that are used solely as method parameters (inputs).

Using Collections and Building Generic Types

12-13

Additional Reading
Defining Generic Interfaces
For more information about generic interfaces, see the Generic Interfaces (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192967. For more information about variant generic interfaces, see the Creating Variant Generic Interfaces (C# and Visual Basic) page at http://go.microsoft.com/fwlink/?LinkId=192968.

Defining and Implementing a Contravariant Interface


For more information about covariance and contravariance in generics, see the Covariance and Contravariance in Generics page at http://go.microsoft.com/fwlink/?LinkId=192969.

12-14

Programming in C# with Microsoft Visual Studio 2010

Lesson 4

Using Generic Methods and Delegates


Contents:
Question and Answers Detailed Demo Steps 15 16

Using Collections and Building Generic Types

12-15

Question and Answers


What Are Generic Methods and Delegates?
Question: When should you use a generic method? Answer: You should use a generic method when you need to define a method that acts on several other unrelated types, and you need to ensure type safety. For example, you may use a type parameter with a method that compares two values. You could use a single type parameter for two method parameters. This ensures that the two parameters are always the same type when the method is invoked, but provides the flexibility to use the same method with several different types.

Using the Generic Delegate Types Included in the .NET Framework


Question: When might you choose not to use the generic delegates that the .NET Framework provides? Answer: This question is designed to stimulate discussion among the students, so there is no definitive answer. Possible reasons include if you need to define a delegate that does not support variance.

Defining a Generic Method


Question: Can you use variance when you define a generic method? Answer: No. You can only use variance when you define a generic interface. However, you can specify a generic method in a generic interface that uses variance.

Using Generic Methods


Question: When you define a generic method, how many type parameters can you specify? Answer: You can specify as many type parameters as you require; there is no limit.

Demonstration: Defining a Generic Delegate


Question: How does defining a generic delegate differ from defining a nongeneric delegate? Answer: When you define a generic delegate, you add type parameters and use the type parameters in the delegate signature. There is no other difference.

12-16

Programming in C# with Microsoft Visual Studio 2010

Detailed Demo Steps


Demonstration: Defining a Generic Delegate
In this demonstration, you will see how to: Define a custom generic delegate. Create an instance of the generic delegate. Create an instance of a generic delegate by using the Action generic delegate type. Invoke the custom generic delegate instance and the Action generic delegate instance. 1. Start Visual Studio: Click Start, point to All Programs, click Microsoft Visual Studio 2010, and then click Microsoft Visual Studio 2010. 2. Open the Module 12, Demo3 starter solution: a. b. 3. On the File menu, point to Open, and then click Project/Solution. Move to the E:\Demofiles\Mod12\Demo3\Starter\DefiningAGenericDelegateDemo folder, and then double-click DefiningAGenericDelegateDemo.sln.

Open the Printer.cs file, and then review the Printer class: In Solution Explorer, double-click Printer.cs, and then describe the Printer class. The Printer class is a generic class that takes a single type parameter named DocumentType. The purpose of the class is to represent a printer that is capable of printing a specific type of document.

4. 5. 6. 7.

Uncomment the code that defines the DocumentAddingToQueueDelegate type. Highlight that the delegate includes a type parameter. Uncomment the code that defines the DocumentAddingToQueue event. Highlight that the event uses the generic delegate that you defined in the previous step. Uncomment the OnDocumentAddingToQueue method and explain how this method is used to raise the event. In the AddDocumentToQueue method, uncomment the code that raises the OnDocumentAddingToQueue event and uses the response to determine whether to add the item to the print queue. Open the Program.cs file, and then review the Program class: In Solution Explorer, double-click Program.cs, and then describe the Program class.

8.

9.

Uncomment the code that adds a handler for the OnDocumentAddingToQueue event, and uncomment the handler method. Explain how the handler method displays a message box and returns a value based on the response.

10. Run the application: On the Debug menu, click Start Without Debugging. 11. In the Reference Guide Printing dialog box, click OK. 12. In the Reference Guide Printing dialog box, click Cancel.

Using Collections and Building Generic Types

12-17

13. In the Reference Guide Printing dialog box, click OK. 14. When the application pauses, verify that only two documents have printed, because you canceled the second document. 15. Close the application. 16. Open the Printer.cs file: In Solution Explorer, double-click Printer.cs. 17. Uncomment the DocumentPrintedEventArgs generic class, and explain how this class inherits from the EventArgs class and exposes a Document property. Explain that this will be used in an event that will notify subscribers that a document has been printed, and provide the document that printed as an argument. 18. Uncomment the code that defines the DocumentPrinted event by using the Action generic delegate. Explain how this event uses an instance of the Printer generic class and an instance of the DocumentPrintedEventArgs generic class as parameters. 19. Uncomment the OnDocumentPrinted method, and explain how this method raises the DocumentPrinted event. 20. In the PrintDocuments method, uncomment the code that calls the OnDocumentPrinted method, and explain how this raises the DocumentPrinted event whenever a document is printed. 21. Open the Program.cs file, and then review the Program class: In Solution Explorer, double-click Program.cs. 22. Uncomment the code that adds a handler for the DocumentPrinted event, and uncomment the handler method. Explain how the handler method displays a message box. 23. Run the application: On the Debug menu, click Start Without Debugging. 24. In the Reference Guide Printing dialog box, click OK. 25. In the Reference Guide Printing dialog box, click Cancel. 26. In the Reference Guide Printing dialog box, click OK. 27. When the application pauses, verify that only two documents printed, because you canceled the second document, and then press ENTER. 28. In the Report Printed dialog box, click OK three times. 29. When the application pauses, verify that only three documents printed. 30. Close the application. 31. Close Visual Studio: In Visual Studio, on the File menu, click Exit.

12-18

Programming in C# with Microsoft Visual Studio 2010

Module Review and Takeaways


Review Questions
1. What are the main advantages of using a collection class instead of an array? Answer: Possible answers include: 2. Collections automatically grow when you add items, whereas arrays do not. You can only access an array by index, whereas you can use keys to access members of a collection.

How do generic collection classes differ from nongeneric collection classes? Answer: Generic collection classes are strongly typed and therefore prevent run-time cast exceptions; non-generic classes use the object type, so they risk run-time errors.

3.

When would you use a generic type instead of a nongeneric type? Answer: You use generic types when you need to define a wrapper or provide functionality for unrelated and possibly unknown types.

Best Practices Related to Collections


Supplement or modify the following best practices for your own work situations: Use collections instead of arrays where you do not know the size of the collection in advance. Use Hashtable objects for large key-value pair collections, but avoid them for smaller collections.

Best Practices Related to Generic Types


Supplement or modify the following best practices for your own work situations: Use generic types wherever possible to improve type safety. Use constraints on generic types to provide control over types that are used with your generic classes.

Best Practices Related to Generic Methods and Delegates


Supplement or modify the following best practices for your own work situations: Use the Action and Func generic delegates instead of custom delegates wherever possible.

Best Practices Related to Variant Interfaces


Supplement or modify the following best practices for your own work situations: Use the in and out keywords to specify covariant and contravariant type parameters wherever possible. In this way, you can make your generic interfaces as flexible as possible.

Using Collections and Building Generic Types

12-19

Lab Review Questions and Answers


Lab A: 1. What namespace did you need to bring into scope before you could use the Hashtable class? Answer: The System.Collections namespace. 2. In the lab, you used a very simple hash to add items to the Hashtable object. How could you create a more complex hash? Answer: You could use the classes in the System.Security.Cryptography namespace to generate a hash value. Lab B: 1. In the lab, you defined a generic interface with a type parameter. How did you constrain the types that can be used with a class that implements this interface? Answer: You used the where keyword and specified that the type must implement the IComparable interface. 2. In the lab, you used the name TItem for the type parameter of the Tree class, and the name TreeItem for the static generic method in the class. Why did you not use the same name in both instances? Answer: The type parameter for the class is still in scope for the generic method, so using the same type name would have introduced ambiguity. Also, if you attempt to use a type parameter defined at the class level in a static method, the type parameter will return null and throw an exception. You should only reuse type parameter names where each previous use is out of scope.

Building and Enumerating Custom Collection Classes

13-1

Module 13
Building and Enumerating Custom Collection Classes
Contents:
Lesson 1: Implementing a Custom Collection Class Lesson 2: Adding an Enumerator to a Custom Collection Class Module Review and Takeaways Lab Review Questions and Answers 2 6 10 11

13-2

Programming in C# with Microsoft Visual Studio 2010

Lesson 1

Implementing a Custom Collection Class


Contents:
Question and Answers Additional Reading 3 5

Building and Enumerating Custom Collection Classes

13-3

Question and Answers


What Are Custom Collection Classes?
Question: When might you develop a custom collection class? Answer: You might develop a custom collection class when you need to implement semantics that are not provided by the collection classes that the .NET Framework base class library provides.

Generic Collection Interfaces in the .NET Framework


Question: When you develop a custom collection class, which interface must you always implement? Answer: You should always implement the ICollection<T> interface when you develop a custom collection class. Other interfaces may also be appropriate, such as the IList<T> interface, but you should implement the ICollection<T> interface in every custom collection class.

Implementing a Simple Custom Collection Class


Question: You develop an application that stores data in a file in a custom format. The file structure is predefined and uses a structure that is similar to, but not the same as, XML. Data that is stored in the file is stored in a specified order, and the application needs to both read and write to the file. How can you use a custom collection class to make it easier to use the data file in the application? Answer: You can develop a custom collection class that uses the file as the data store. You can implement the standard interfaces in your collection class, including the IList<T> interface, because you are developing a sequential collection. Applications can then use your collection type to read and write data to the file by using standard C# programming constructs; they do not require any knowledge of the underlying file or its structure.

Implementing a Dictionary Collection Class


Question: You develop a dictionary collection class and implement the IDictionary<TKey, TValue> interface. You must use the underlying Dictionary<TKey, TValue> class as an internal data store. When you implement the CopyTo method that the interface requires, you discover that the generic dictionary class does not expose a public CopyTo method. The generic dictionary class implements the CopyTo method that the interface defines explicitly. Implementing the interface explicitly avoids exposing the CopyTo method when referencing a collection by using the Dictionary<TKey, TValue> type. When might you use this approach in collections that you develop? Answer: Implementing interface members explicitly is a convenient way to hide methods that do not make sense in terms of your collection. In the case of the dictionary class, it does not make sense to use the CopyTo method on a dictionary collection of keys and values; however, if you cast the a dictionary collection as an instance of the ICollection<T> interface, it makes more sense to copy to an array, because you will copy instances of the KeyValuePair<TKey, TValue?> class rather than the keys and values individually. Another example is the Add method. The ICollection<T> interfaces requires an Add method, but in many collections, this does not make sense; for example, you use the Queue class to enqueue and dequeue an item rather than add and remove it. When you implement the Add method explicitly,

13-4

Programming in C# with Microsoft Visual Studio 2010

you can hide the method, and applications that refer to your collection by using an interface reference will work correctly. An interface member that is implemented explicitly can still be accessed and should be implemented fully.

Building and Enumerating Custom Collection Classes

13-5

Additional Reading
Generic Collection Interfaces in the .NET Framework
For more information about the ICollection<T> interface, see the ICollection(OfT) Interface page at http://go.microsoft.com/fwlink/?LinkId=192970. For more information about the IList<T> interface, see the IList(OfT) Interface page at http://go.microsoft.com/fwlink/?LinkId=192971. For more information about the IDictionary<TKey, TValue> interface, see the IDictionary(OfTKey, TValue) Interface page at http://go.microsoft.com/fwlink/?LinkId=192972.

13-6

Programming in C# with Microsoft Visual Studio 2010

Lesson 2

Building Dynamic LINQ Queries and Expressions


Contents:
Question and Answers Additional Reading 7 9

Building and Enumerating Custom Collection Classes

13-7

Question and Answers


What Is an Enumerator?
Question: An enumerator provides read-only access to items in a collection. Why would it be inappropriate to permit write access to items that are accessed by using an enumerator? Answer: This question is designed to stimulate discussion among the students, so there is no definitive answer. One problem with permitting write access to an enumerator is that enumerators often return data in a specific order. Changing the value of an item in the collection may cause the item to be out of order in the collection. This may cause unexpected side effects.

What Is the IEnumerable<T> Interface?


Question: How does the foreach statement use the IEnumerable<T> interface? Answer: The foreach statement uses the GetEnumerator method that the IEnumerable<T> interface exposes to retrieve the default enumerator for a type when no other enumerator is explicitly specified.

What Is the IEnumerator<T> Interface?


Question: How does the MoveNext method indicate to the caller that advancing any further would result in an invalid state because the enumerator has reached the end of the collection? Answer: The MoveNext method returns false when it has reached the end of the collection.

Implementing an Enumerator Manually


Question: In the code example on the slide that is associated with this topic, the get accessor checks that the value of the pointer variable is not 1 before it returns a value. 1 is the initial value for the pointer. Why would 1 be the initial value, and why does the Reset method set the pointer back to 1? Answer: The value 1 will throw an exception if you attempt to use it as an index in an array. If you increment 1, you get 0, which is the index of the first item in an array. When you use an enumerator, the enumerator should always start in an invalid state, and you should call the MoveNext method before you access the Current property for the first time. Setting the pointer to 1 ensures that after you have called the MoveNext method for the first time, the enumerator is ready to return the first item from the collection. The Reset method should return the enumerator to its initial invalid state, so it must set the value to 1. If the Reset method set the value to 0, when the MoveNext method was invoked, it would advance the enumerator to index 1; this is the second item in the collection, and the first item (index 0) would be skipped.

Implementing an Enumerator by Using an Iterator


Question: How can you use an iterator in conjunction with a property to expose an enumerator? Answer: You can expose a property that returns an instance of the IEnumerable<T> interface. You implement the get accessor for the property by using an iterator that uses the yield return keywords

13-8

Programming in C# with Microsoft Visual Studio 2010

to return items from your collection in the required order. You can then use the property where you would use an enumerator, for example, in a foreach statement.

Building and Enumerating Custom Collection Classes

13-9

Additional Reading
What Is the IEnumerable<T> Interface?
For more information about the IEnumerable<T> interface, see the IEnumerable(OfT) Interface page at http://go.microsoft.com/fwlink/?LinkId=192973.

What Is the IEnumerator<T> Interface?


For more information about the IEnumerator<T> interface, see the IEnumerator(OfT) Interface page at http://go.microsoft.com/fwlink/?LinkId=192974.

Implementing an Enumerator by Using an Iterator


For more information about iterators, see the Iterators (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192975. For more information about the yield keyword, see the yield (C# Reference) page at http://go.microsoft.com/fwlink/?LinkId=192976.

13-10

Programming in C# with Microsoft Visual Studio 2010

Module Review and Takeaways


Review Questions
1. What are the advantages of developing a custom collection class? Answer: A custom collection class enables you to use a custom internal representation for data that is based on how you need to represent the data, and it enables you to use custom sorting. 2. You want to ensure that your custom collection class can be enumerated by using a foreach statement, and you need to support collection initializers with your type. What steps would you take to achieve this? Answer: Implement generic interfaces for collection classes such as the ICollection interface, the IList interface, or the IDictionary interface. 3. You develop a custom collection class. Applications that consume your class need to iterate over the data that is stored in your collection class in several different ways and obtain data in different orders. How would you implement this functionality in a custom collection class, and how would you provide a default order for iterating over the data in your collection class? Answer: Add properties or methods to the class that return instances of the IEnumerable<T> interface; you can use each instance to return data that is ordered according to specific requirements. To implement a default order, implement the IEnumerable<T> interface in your type and expose a GetEnumerator method. The enumerator that the GetEnumerator method returns is the default enumerator that is used with your type when no other enumerator is specified.

Best Practices Related to Developing Custom Collection Classes


Supplement or modify the following best practices for your own work situations: Implement the appropriate interfaces to ensure that your class is compatible with the standard collection-handling constructs in C#. Always use the generic interfaces in preference to nongeneric interfaces when you develop a custom collection class.

Best Practices Related to Implementing Enumerators


Supplement or modify the following best practices for your own work situations: Implement the IEnumerable<T> interface to define a default enumerator for your type. Expose additional enumerators by using a property or a method in your custom collection class. Implement enumerators by using iterators to minimize the possibility of errors in your code.

Building and Enumerating Custom Collection Classes

13-11

Lab Review Questions and Answers


1. In the lab, you implemented the IList<T> interface. When would you use the IList<T> interface in a custom class? Answer: You would use the IList<T> interface when you develop a custom collection class to store items in a linear collection that you can access by using an index. 2. In the lab, you exposed a second enumerator to iterate through the collection in reverse order. How do iterators enable you to implement enumerators with minimal code? Answer: You use an iterator to return items from the collection in the appropriate order. When you implement an iterator, you do not need to implement the MoveNext or Reset methods or the Current property; the compiler generates an enumerator that is based on the values that are returned and implements these methods and properties for you. This reduces the effort that is required to implement the enumerator.

Using LINQ to Query Data

14-1

Module 14
Using LINQ to Query Data
Contents:
Lesson 1: Using the LINQ Extension Methods and Query Operators Lesson 2: Building Dynamic LINQ Queries and Expressions Module Review and Takeaways Lab Review Questions and Answers 2 7 11 12

14-2

Programming in C# with Microsoft Visual Studio 2010

Lesson 1

Using the LINQ Extension Methods and Query Operators


Contents:
Question and Answers Additional Reading 3 6

Using LINQ to Query Data

14-3

Question and Answers


What Is the Purpose of LINQ?
Question: Briefly summarize the purpose of LINQ. Answer: The purpose of LINQ is to simplify the development of data-processing logic by providing features that abstract the mechanisms that are required to query data from the code in your applications.

Querying Data and Building a Result Set


Question: In the following code example, what does the employeeDetails array contain?
var employeeDetails = employees.Select(empl => empl.ID);

Answer: A reference to an enumerable collection of employee IDs.

Filtering Data
Question: What does the result object represent in the following code example?
IEnumerable<Customer> customers { new Customer{ FirstName = new Customer{ FirstName = new Customer{ FirstName = new Customer{ FirstName = new Customer{ FirstName = new Customer{ FirstName = new Customer{ FirstName = }; = new[] "Luka", LastName="Abrus", Age = 41}, "Syed", LastName="Abbas", Age = 23}, "Keith", LastName="Harris", Age = 59}, "David", LastName="Pelton", Age = 25}, "John", LastName="Peoples", Age = 37}, "Toni", LastName="Poe", Age = 29}, "Jeff", LastName="Price", Age = 74}

var result = customers.Where(cust => cust.LastName == "Poe");

Answer: The result object represents a reference to an IEnumerable<Customer> object that contains all of the customers that have a last name of Poe.

Ordering Data
Question: Which extension method would you use to sort an array of strings into descending order? Answer: The OrderByDescending extension method.

Grouping Data and Performing Aggregate Calculations


Question: In the following code example, what does the result object contain?
IEnumerable<Customer> customers { new Customer{ FirstName = new Customer{ FirstName = new Customer{ FirstName = new Customer{ FirstName = = new[] "Luka", LastName="Abrus", Age = "Syed", LastName="Abbas", Age = "Keith", LastName="Harris", Age "David", LastName="Pelton", Age 41}, 23}, = 59}, = 41},

14-4

Programming in C# with Microsoft Visual Studio 2010

new Customer{ FirstName = "John", LastName="Peoples", Age = 23}, new Customer{ FirstName = "Toni", LastName="Poe", Age = 29}, new Customer{ FirstName = "Jeff", LastName="Price", Age = 23} }; var result = customers.Count(cust => cust.LastName.StartsWith("P"));

Answer: The result object contains the numeric value 4.

Joining Data from Different Data Sets


Question: In the following code example, what does the result object contain?
IEnumerable<CellPhone> phones = new[] { new CellPhone { ID =1, Make="...", Model="...", NetworkID=1}, new CellPhone { ID =2, Make="...", Model="...", NetworkID=1}, new CellPhone { ID =3, Make="...", Model="...", NetworkID=2}, }; IEnumerable<CellPhoneNetwork> networks = new[] { new CellPhoneNetwork { ID =1, Name="..."}, new CellPhoneNetwork { ID =2, Name="..."} }; var result = phones. Select(p => p). Join( networks, p => p.NetworkID, n => n.ID, (p, n) => new { p.Make, p.Model, n.Name });

Answer: The result object contains an enumerable result set that contains a new type that models the make and model of the cell phone, and the network name.

Using C# LINQ Query Operators


Question: In the following code examples, are both queries equivalent?
IEnumerable<double> payments = new[] {232.12, 8378.53, 66.01, 4312.11, 156.00}; var queryOperatorResult = (from payment in payments where payment > 100 && payment < 500 select payment).Max(); var extensionMethodResult = payments.Where(payment => payment > 100 && payment < 500).Max()

Answer: Yes, both code examples produce the same result of 232.12

Deferred and Early Evaluation of Queries


Question: In your application, you construct a LINQ query to retrieve all of the employee records from a database. In your code, after the LINQ query, you add a foreach statement to iterate through each record. You start to debug and step over the LINQ query and then pause before you enter the

Using LINQ to Query Data

14-5

foreach statement. You then make a change to one of the employee records in the database. Finally, you return to the Microsoft Visual Studio debugger and continue to step into the foreach statement. Will the change that you made to the employee record be visible when you iterate through the results? Answer: Yes. The change will be visible because the LINQ query is not evaluated until the foreach statement implicitly invokes the GetEnumerator method.

14-6

Programming in C# with Microsoft Visual Studio 2010

Additional Reading
What Is the Purpose of LINQ?
For more information about LINQ, see the Language-Integrated Query (LINQ) page at http://go.microsoft.com/fwlink/?LinkId=192977.

Querying Data and Building a Result Set


For more information about LINQ expressions, see the LINQ Query Expressions (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192978. For more information about anonymous types, see the Anonymous Types (C# Programming Guide) page at http://go.microsoft.com/fwlink/?LinkId=192979.

Using C# LINQ Query Operators


For more information about LINQ query operators, see the LINQ Query Syntax versus Method Syntax (C#) page at http://go.microsoft.com/fwlink/?LinkId=192980.

Deferred and Early Evaluation of Queries


For more information about LINQ queries and deferred evaluation, see the Introduction to LINQ Queries (C#) page at http://go.microsoft.com/fwlink/?LinkId=192981.

Using LINQ to Query Data

14-7

Lesson 2

Building Dynamic LINQ Queries and Expressions


Contents:
Question and Answers Additional Reading 8 10

14-8

Programming in C# with Microsoft Visual Studio 2010

Question and Answers


What Is a Dynamic LINQ Query?
Question: When might you use a dynamic LINQ query instead of a static LINQ query? Answer: You might use a dynamic LINQ query if you do not know the full details of the query when you develop the application.

What Is an Expression Tree?


Question: How can you extend the tree in the following diagram to satisfy the expression (o.x > 3 && o.y > 6) ||o. y > 20?
&& / ---------/ > / / \ \ / / \ ---------\ > \ \ / \ Member: o.y Constant: 6

/ \ Member: o.x Constant: 3

Answer: You can add an extra branch to the tree, as the following diagram shows.
|| / ---------/ / / / && / -------------/ > / / / Member: o.x \ \ \ Constant: 3 / / Member: o.y / \ -------------\ > \ \ \ Constant: 6 / / Member: o.y / \ ---------\ > \ \ \ Constant: 20

The Expression Types


Question: How would you define an expression that checks whether a member named x is equal to the constant value 24? Answer: Create a Member Expression object to represent the member x and a Constant Expression object to represent the constant value 24. You would then combine the two expressions into a BinaryExpression expression by using the static Equal method.

Using LINQ to Query Data

14-9

Obtaining Type Information at Run Time


Question: What is the result of calling the GetProperty method on an instance of the Type class that represents the string type and providing the string "ToString" as the argument? Answer: Although the string type does contain a member named ToString, the member is a method, not a property, so the GetProperty method will return null. If you attempt to use the MemberInfo object, your application may throw a NullReferenceException exception.

Compiling and Running a Dynamic LINQ Query


Question: What is the purpose of the Compile method? Answer: The Compile method converts an expression tree into an executable lambda expression. You can use the lambda expression as a handler for a delegate or invoke the expression by using dynamic invocation.

14-10

Programming in C# with Microsoft Visual Studio 2010

Additional Reading
What Is an Expression Tree?
For more information about expression trees, see the Expression Trees (C# and Visual Basic) page at http://go.microsoft.com/fwlink/?LinkId=192982.

The Expression Types


For more information about the expression types in the System.Linq.Expressions namespace, see the System.Linq.Expressions Namespace page at http://go.microsoft.com/fwlink/?LinkId=192983. For more information about the Expression class, see the Expression Class page at http://go.microsoft.com/fwlink/?LinkId=192984.

Compiling and Running a Dynamic LINQ Query


For more information about using expression trees to build dynamic queries, see the How to: Use Expression Trees to Build Dynamic Queries (C# and Visual Basic) page at http://go.microsoft.com/fwlink/?LinkId=192985.

Using LINQ to Query Data

14-11

Module Review and Takeaways


Review Questions
1. Review Questions Which query operator would you use to implement filtering functionality on an enumerable collection? Answer: The where query operator. 2. Which extension method would you use to remove duplicate values from an enumerable collection? Answer: The Distinct extension method. 3. How can you force early evaluation of a LINQ query? Answer: By calling a method such as ToList or ToArray. 4. When would you use an expression tree in an application? Answer: You would use an expression tree in an application when you need the application to be highly flexible. An expression tree represents a lambda expression, and you can build the expression tree based on the requirements at run time. You can then compile the expression tree into an executable lambda expression that you can use anywhere that you would normally use a lambda expression; this includes invoking the lambda expression dynamically if you require it.

Best Practices Related to Using LINQ


Supplement or modify the following best practices for your own work situations: Use LINQ queries rather than manually writing your own code to retrieve data and to help reduce dependencies that your applications have on the structure that data sources use. Use anonymous types to model the data that queries return instead of creating new types.

Best Practices Related to Using Dynamic LINQ


Supplement or modify the following best practices for your own work situations: Use dynamic LINQ queries where you require flexibility rather than developing several variants of a query, which risks introducing errors and duplicate code. Use the Type and MemberInfo classes to reference types and type members. Use the typeof keyword and the Get methods (such as GetProperty) minimally to avoid excessive performance issues.

14-12

Programming in C# with Microsoft Visual Studio 2010

Lab Review Questions and Answers


1. In Exercise 1 of the lab, did the application perform deferred or early evaluation of the LINQ query? Answer: Deferred evaluation. The query was evaluated in a foreach statement. 2. In Exercise 2, which static method did you use to construct an expression tree that represented a complete lambda expression? Answer: The static Expression.Lambda method.

Integrating Visual C# Code with Dynamic Languages and COM Components

15-1

Module 15
Integrating Visual C# Code with Dynamic Languages and COM Components
Contents:
Lesson 1: Integrating Visual C# Code with Ruby and Python Lesson 2: Accessing COM Components from Visual C# Module Review and Takeaways Lab Review Questions and Answers 2 7 11 12

15-2

Programming in C# with Microsoft Visual Studio 2010

Lesson 1

Integrating Visual C# Code with Ruby and Python


Contents:
Question and Answers Detailed Demo Steps Additional Reading 3 4 6

Integrating Visual C# Code with Dynamic Languages and COM Components

15-3

Question and Answers


What Is the Dynamic Language Runtime?
Question: What is the purpose of the DLR? Answer: The DLR enables you to integrate components and technologies that perform run-time type checking into a Visual C# application. The DLR uses binders to determine the type information for a dynamic component at run time, to resolve and dispatch method calls to a dynamic component, and to marshal and unmarshal data between the common language runtime (CLR) and the dynamic component.

Using the dynamic Keyword


Question: What is the difference between the var keyword and the dynamic keyword? Answer: The var keyword indicates that the compiler should determine the type of a variable statically, at compile time. A variable that is declared as var is strongly typed. The dynamic keyword specifies that the compiler should not attempt to determine the type of a variable, and the DLR will ascertain type information at run time.

Instantiating a Dynamic Object


Question: Why does the .NET Framework not define a constructor for the dynamic type? Answer: There are two reasons: 1. 2. There is no such type as dynamic. All variables declared as dynamic are objects. A dynamic object is the responsibility of the runtime that hosts the object. The runtime creates the object, but it must provide a way for Visual C# to inform it to perform this task. The common strategy is to use a factory method that the runtime defines and call this factory method from Visual C#.

Invoking and Using a Dynamic Object


Question: Why do you think that you cannot pass a lambda expression as an argument to a method of a dynamic object? Answer: The Visual C# compiler needs to be able to determine, at compile time, the type that a lambda expression returns. The type information for parameters of methods for dynamic objects is not available until run time.

15-4

Programming in C# with Microsoft Visual Studio 2010

Detailed Demo Steps


Demonstration: Calling Python Code from Visual C#
Demonstration Steps
1. 2. Log on to the 10266A-GEN-DEV virtual machine as Student with the password Pa$$word. Open the Python file CustomerDB.py in the E:\Demofiles\Mod15 folder: a. b. c. 3. Using Windows Explorer, move to the E:\Demofiles\Mod15 folder. Right-click CustomerDB.py, and then click Open with. In the Open with dialog box, click Notepad, and then click OK.

Walk through the code. Point out the following items in the Python file: The Customer class, which models a customer. The __init__ method is the constructor. The __str__ method returns a string representation of the customer. The CustomerDB class, which acts as a container for a collection of customers. The __init__ method initializes a list to hold customers. The storeCustomer method adds a customer to the list. The getCustomer method retrieves a customer from the list, and the __str__ method returns the entire list as a formatted string. The GetNewCustomer method, which is a factory method for creating new Customer objects. The GetCustomerDB method, which is a factory method for creating CustomerDB collection objects.

4. 5.

Close the Python file. Start Visual Studio: Click Start, point to All Programs, click Microsoft Visual Studio 2010, and then click Microsoft Visual Studio 2010.

6.

Open the PythonInteroperability solution in the E:\Demofiles\Mod15\PythonInteroperability folder: a. b. On the File menu, point to Open, and then click Project/Solution. Move to the E:\Demofiles\Mod15\PythonInteroperability folder, and then doubleclick PythonInteroperability.sln.

7.

Display the code for the project: In Solution Explorer, expand the PythonInteroperability project, and then double-click Program.cs.

8.

Walk through the code in the Main method. Point out the following items: The CreateRuntime method of the Python class, which is used to create the Python runtime. The UseFile method that references the CustomerDB.py file. The statement that calls the GetNewCustomer method to create a new Python Customer object and store the reference in a variable that is declared as dynamic.

Integrating Visual C# Code with Dynamic Languages and COM Components

15-5

The statement that calls the GetCustomerDB method to create a new instance of the CustomerDB collection class. The value is returned into a variable that is declared as dynamic. The statement that calls the storeCustomer method to add the Customer object to the CustomerDB collection. The value is stored in a third variable that is declared as dynamic. The statements that call the GetNewCustomer method to create a second customer and the storeCustomer method to add this Customer object to the CustomerDB collection. The Console.WriteLine statement that displays the CustomerDB object. Mention that this statement implicitly calls the ToString method to render the object as a string, which is in turn converted into a call to the __str__ method of the CustomerDB object. 9. Show the references that the solution uses: a. b. In Solution Explorer, expand References. Point out the references to the IronPython and Microsoft.Scripting assemblies, which together provide access to the IronPython runtime.

10. Build and run the application: a. b. c. On the Build menu, click Build Solution. On the Debug menu, click Start Without Debugging. Verify that the application generates the following output: Testing Python Customers ID: 100 Name: Fred ID: 101 Name: Sid 11. Close the console window. 12. Close Visual Studio. Telephone: 888 Telephone: 999

15-6

Programming in C# with Microsoft Visual Studio 2010

Additional Reading
What Is the Dynamic Language Runtime?
For more information about the DLR, see the Dynamic Language Runtime Overview page at http://go.microsoft.com/fwlink/?LinkId=192986.

Using the dynamic Keyword


For more information about the dynamic keyword, see the dynamic (C# Reference) page at http://go.microsoft.com/fwlink/?LinkId=192987.

Integrating Visual C# Code with Dynamic Languages and COM Components

15-7

Lesson 2

Accessing COM Components from Visual C#


Contents:
Question and Answers Additional Reading 8 9

15-8

Programming in C# with Microsoft Visual Studio 2010

Question and Answers


Interoperating with COM from a Visual C# Application
Question: Why is it necessary to create an RCW to invoke a COM component from a Visual C# application? Answer: COM components run in unmanaged space and are not controlled by the CLR. The RCW is responsible for instantiating the COM component and destroying it when the Visual C# application has finished with it. The RCW also acts as a proxy for the COM object, calling methods on the COM object when directed by the Visual C# application and converting data between the formats that COM and the CLR expect.

Creating a COM Interop Assembly


Question: Why are PIAs important? Answer: PIAs are important because they provide unique type identity. The PIA distinguishes the verified type definitions that the publisher of a COM component signs from possible fake or malicious definitions provided by other interop assemblies.

Instantiating a COM Component by Using a Runtime Callable Wrapper


Question: What is the difference between instantiating a C# object and a COM object in a C# application? Answer: To instantiate a C# object, you explicitly invoke the constructor for the corresponding C# class and assign the result to a variable of the same type or of an interface that the type implements. To instantiate a COM object, you invoke a constructor for the managed wrapper around a COM interface that a COM coclass implements. This managed wrapper is defined in the RCW for the COM component.

Calling Methods on a COM Object


Question: If you omit an argument to a COM method, what value does the RCW use as the default? Answer: The Type.Missing value.

Deploying Without a Primary Interop Assembly


Question: If you specify PIA-less deployment, when you deploy an application that uses a COM component, is it still necessary to deploy the COM component, too? Answer: Yes. PIA-less deployment only embeds information about the interop assembly into the application assembly. It is still necessary to deploy the COM component that the interop assembly references.

Integrating Visual C# Code with Dynamic Languages and COM Components

15-9

Additional Reading
Interoperating with COM from a Visual C# Application
For more information about marshaling COM data types, see the COM Data Types page at http://msdn.microsoft.com/en-us/library/sak564ww(v=VS.100).aspx.

Creating a COM Interop Assembly


For more information about using the Tlbimp utility, see the Tlbimp.exe (Type Library Importer) page at http://go.microsoft.com/fwlink/?LinkId=192988.

Instantiating a COM Component by Using a Runtime Callable Wrapper


Managing the Lifetime of a COM Object COM performs its own memory management, separate from that of the CLR. When you create a COM object, the COM subsystem allocates memory for that object. When an unmanaged COM client application creates or adds a reference to a COM object, it must indicate this fact to the COM object by calling its AddRef method. This method increments a reference counter in the COM object. When an unmanaged COM client application has finished using an object, it must call the Release method. This method decrements the reference counter. If the reference counter reaches zero, the COM object is destroyed and the memory that it used is released. When you use COM Interop from a managed application, the RCW automatically handles the lifetime management of a COM object by calling AddRef when you instantiate a COM object and by calling Release when you finish using the RCW. The CLR finalizes the COM object before the CLR collects garbage. If you must release a COM object early, you can call the ReleaseComObject method of the Marshal class to decrement the reference count of the COM object, or you can call the FinalReleaseComObject method to set the reference count to zero. Note: The Marshal class contains a selection of other methods that you can use to allocate and free memory for unmanaged COM objects and obtain information about COM objects, classes, and interfaces. Managing COM Apartments from Managed Code COM objects execute in apartments. An apartment specifies whether the COM component uses a singlethreaded or multithreaded model when it runs. When a managed application creates a COM object, the CLR creates an apartment for the COM object by examining the ApartmentState property of the managed thread that is calling the COM object. If the ApartmentState property of the managed thread matches the apartment requirements of the COM component, the CLR instantiates the COM object in this apartment. Every method call to the COM object from managed code passes through the interop marshaler to the COM object in unmanaged space. If the ApartmentState property of the managed thread does not match the apartment requirements of the COM component, the CLR instantiates the COM object in a new apartment with the appropriate threading model. Every method call that the managed application makes is marshaled by the interop marshaler to unmanaged space and then by the COM marshaler to the new apartment. The COM marshaler ensures that method calls are synchronized correctly between apartments that implement different threading models. This is known as crossapartment marshaling. The CLR runs managed threads by using the multithreaded apartment (MTA) model by default. However, you can modify this behavior by calling the SetApartmentState method of a thread to set the apartment state to ApartmentState.STA to specify the single-threaded apartment (STA) model. You must set the apartment state before the thread starts to run. If you must modify the apartment state of the initial

15-10

Programming in C# with Microsoft Visual Studio 2010

thread that runs an application, you can apply the MTAThread or STAThread attributes to the Main method of the application. Note: If you create an application by using the Windows Application template in Visual Studio, the template tags the Main method with the STAThread attribute. You must not change this attribute, because a Windows graphical user interface (GUI) expects all of the user interaction to occur in a single thread. If you must call COM components that use the MTA model from a Windows application by using a GUI, you should consider creating an additional thread for calling these COM components and then set the ApartmentState property of this thread to ApartmentState.MTA. Cross-apartment marshaling can be expensive and time consuming, so you should try to ensure that managed code calls COM components by using the same apartment. However, this may not always be feasible. If the same managed thread makes calls to STA COM components and MTA COM components, some cross-apartment COM marshaling is unavoidable. As a workaround, you have at least two choices. You could create a new thread for each COM component that you want to use and set its ApartmentState property appropriately (this might prove to be more expensive than performing crossapartment marshaling if you use it to excess). Alternatively, you could try to ensure that the COM components that you use support the Both COM threading model so that they can run in single-threaded and multithreaded apartments.

Calling Methods on a COM Object


Handling Exceptions in COM Method Calls When you call a method in a COM object, it can report error conditions. A COM object usually returns an HRESULT value from the method to report an error. The S_OK value indicates that the method call was successful. Any other value indicates an error, and the value itself specifies the reason for the error. An RCW does not pass HRESULT values back to managed client applications as return values. Instead, the RCW either returns no value at all or returns the value of any parameter that is marked with the retval COM attribute in the code that defines the COM method. (retval is an attribute that the Microsoft IDL (MIDL) compiler uses to indicate that a parameter should be marshaled as the return value.) If a COM method attempts to pass back an HRESULT value other than S_OK, the CLR traps it and raises a managed exception. The managed exception that it raises depends on the value of HRESULT. The CLR automatically maps several well-known COM HRESULT values to the equivalent managed exception. For example, the HRESULT value E_NULLREFERENCE causes the CLR to raise a NullReferenceException exception. You can find a full list of HRESULT mappings in the Visual Studio 2005 documentation. If a COM method returns an unrecognized HRESULT value, the CLR raises a COMException exception. The HRESULT value that the COM method returns is available in the ErrorCode property of the COMException object. In addition, if the COM object supports the COM IErrorInfo interface, the Message property of the COMException object is populated with the string that the IErrorInfo.GetDescription method returns, the Source property is filled in with the return value from the IErrorInfo.GetSource method, and the HelpLink property contains information that the IErrorInfo.GetHelpFile and IErrorInfo.GetHelpContext methods return.

Integrating Visual C# Code with Dynamic Languages and COM Components

15-11

Module Review and Takeaways


Review Questions
1. What is the difference between the dynamic type and the object type? Answer: Strictly speaking, dynamic is not a type. It is an instance of the object type that has type checking deferred until run time. 2. What is the difference between an interop assembly and an RCW? Answer: An interop assembly contains the definitions of the types and interfaces that a COM component exposes. The CLR uses the interop assembly to create an RCW when an application runs. The RCW acts as a proxy to the COM component for the application.

Best Practices Related to Integrating Visual C# Code with Dynamic Languages


Supplement or modify the following best practices for your own work situations: Do not use the dynamic keyword as a substitute for the var keyword. A variable defined as var is strongly typed and all references are checked at compile time. A variable defined as dynamic is only checked at run time and imposes an additional overhead at run time. Program defensively. Do not assume when you build an application that uses scripts that are based on dynamic languages that those scripts will be well-behaved. Be prepared to catch and handle exceptions that scripts cause. Be prepared to catch and handle exceptions that are caused by missing scripts or unexpected versions of the runtime for the dynamic language. Only use scripts from trusted sources.

Best Practices Related to Accessing COM Components from Visual C#


Supplement or modify the following best practices for your own work situations: Ensure that any COM components that an application uses are installed and available on the computer that runs your application. Be prepared to catch and handle exceptions that missing COM components cause. Use PIA-less deployment. Only use COM components that trusted sources provide.

15-12

Programming in C# with Microsoft Visual Studio 2010

Lab Review Questions and Answers


1. Which component is responsible for translating Visual C# method calls to a Python object into Python method calls? Answer: The Python binder. 2. Which component is responsible for translating values that a Python method returns into a format that a Visual C# application can use? Answer: The Python binder (again). 3. How did you create the interop assembly that your application used to interact with Office Excel? Answer: You did not create the interop assembly. You added a reference to the PIA that Microsoft that providesit is supplied with Office Excel.

Programming in C# with Microsoft Visual Studio 2010

R-1

Resources
Contents:
Microsoft Learning TechNet and MSDN Content Communities 2 3 7

R-2

Programming in C# with Microsoft Visual Studio 2010

Microsoft Learning
This section describes various Microsoft Learning programs and offerings. Microsoft Skills Assessments Describes the skills assessment options available through Microsoft Microsoft Learning Describes the training options available through Microsoft face-to-face or self-paced Microsoft Certification Program Details how to become a Microsoft Certified Professional, Microsoft Certified Database Administrators, and more Microsoft Learning Support To provide comments or feedback about the course, send e-mail to support@mscourseware.com To ask about the Microsoft Certification Program (MCP), send e-mail to mcphelp@microsoft.com

Programming in C# with Microsoft Visual Studio 2010

R-3

TechNet Content
There is no content from Technet in this course.

MSDN Content
This section includes content from MSDN for this course

Module 1
Microsoft .NET Visual C# What's New in Visual C# 2010 Assemblies in the Common Language Runtime Assembly Versioning Sign Tool (SignTool.exe) .NET Framework Tools Console Class Introduction to Windows Presentation Foundation Video How to: Create a C# WPF Application Control Library XML Documentation Comments (C# Programming Guide) Recommended Tags for Documentation Comments (C# Programming Guide) Main() Command-Line Arguments (C# Programming Guide)

Module 2
C# Keywords General Naming Conventions Capitalization Conventions 3.7 Scopes Convert Class Const (C# Reference) C# Operators Operators (C# Programming Guide) StringBuilder class Harness the Features of C# to Power Your Scientific Computing Projects Single-Dimensional Array (C# Programming Guide) Multidimensional Array (C# Programming Guide) Jagged Array (C# Programming Guide)

R-4

Programming in C# with Microsoft Visual Studio 2010

Array Class ?: Operator (C# Reference)

Module 3
Methods (C# Programming Guide) Member Overloading params (C# Reference) Refactoring (C#) Named and Optional Arguments (C# Programming Guide) out parameter modifier (C# Reference)

Module 4
try-catch (C# Reference) Exception Members try-finally (C# Reference) Checked and Unchecked (C# Reference)

Module 5
File Class FileInfo Class Directory Class DirectoryInfo Class Path Class FileStream Class StreamWriter Class StreamReader Class BinaryWriter Class BinaryReader Class

Module 6
Enumeration Types (C# Programming Guide) Instance Constructors (C# Programming Guide) Partial Classes and Methods (C# Programming Guide) ref (C# Reference) Boxing and Unboxing (C# Programming Guide)

Module 7
private (C# Reference)

Programming in C# with Microsoft Visual Studio 2010

R-5

public (C# Reference) internal (C# Reference) static (C# Reference) Extension Methods (C# Programming Guide) Classes and Structs (C# Programming Guide)

Module 8
Object Class (System) Polymorphism (C# Programming Guide) Explicit Interface Implementation (C# Programming Guide) Abstract and Sealed Classes and Class Members (C# Programming Guide) abstract (C# Reference) as (C# Reference) is (C# Reference)

Module 9
3.9 Automatic memory management Destructors (C# Programming Guide) GC Members Implementing a Dispose Method using Statement (C# Reference)

Module 10
Properties (C# Programming Guide) Using Properties (C# Programming Guide) Interface Properties (C# Programming Guide) Choosing Between Properties and Methods Comparison Between Properties and Indexers (C# Programming Guide) Using Indexers (C# Programming Guide) Object.Equals Method (Object)

Module 11
Delegates (C# Programming Guide) Asynchronous Programming Overview Lambda Expressions (C# Programming Guide) Events (C# Programming Guide) How to: Publish Events that Conform to .NET Framework Guidelines (C# Programming Guide) How to: Run an Operation in the Background

R-6

Programming in C# with Microsoft Visual Studio 2010

Anonymous Methods (C# Programming Guide) How to: Hook Up Events By Using IntelliSense (C#)

Module 12
Commonly Used Collection Types Object and Collection Initializers Generics Constraints on Type Parameters Generic Interfaces Creating Variant Generic Interfaces Covariance and Contravariance in Generics

Module 13
ICollection(T) Interface IList(T) Interface IDictionary(TKey, TValue) Interface IEnumerable (T) Interface IEnumerator (T) Interface Iterators (C# Programming Guide) yield (C# Reference)

Module 14
Language-Integrated Query (LINQ) LINQ Query Expressions (C# Programming Guide) Anonymous Types (C# Programming Guide) LINQ Query Syntax versus Method Syntax (C#) Introduction to LINQ Queries (C#) Expression Trees (C# and Visual Basic) System.Linq.Expressions Namespace Expression Class How to: Use Expression Trees to Build Dynamic Queries

Module 15
Dynamic Language Runtime Overview dynamic (C# Reference) Tlbimp.exe (Type Library Importer)

Programming in C# with Microsoft Visual Studio 2010

R-7

Communities
Microsoft Technical Communities Web site.

R-8

Programming in C# with Microsoft Visual Studio 2010

Send Us Your Feedback


You can search the Microsoft Knowledge Base for known issues at Microsoft Help and Support before submitting feedback. Search using either the course number and revision, or the course title. Note Not all training products will have a Knowledge Base article if that is the case, please ask your instructor whether or not there are existing error log entries.

Courseware Feedback
Send all courseware feedback to support@mscourseware.com. We truly appreciate your time and effort. We review every e-mail received and forward the information on to the appropriate team. Unfortunately, because of volume, we are unable to provide a response but we may use your feedback to improve your future experience with Microsoft Learning products.

Reporting Errors
When providing feedback, include the training product name and number in the subject line of your email. When you provide comments or report bugs, please include the following: Document or CD part number Page number or location Complete description of the error or suggested change

Please provide any details that are necessary to help us verify the issue.

Important All errors and suggestions are evaluated, but only those that are validated are added to the product Knowledge Base article.

Anda mungkin juga menyukai