楼主: bnso

Introduction to C# Programming

[复制链接]
论坛徽章:
49
NBA季后赛之星
日期:2014-10-19 19:51:33蓝锆石
日期:2014-10-19 19:51:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33问答徽章
日期:2014-04-15 10:41:44优秀写手
日期:2014-07-24 06:00:11保时捷
日期:2014-10-19 19:51:33三菱
日期:2014-10-19 19:51:33
101#
 楼主| 发表于 2006-8-13 21:33 | 只看该作者
42 Module 8: Using Reference-Type Variables
? To test the program
1. Open a Command window and go to the install folder\
Labs\Lab08\Starter\CopyFileUpper \bin\debug folder.
2. Execute CopyFileUpper .
3. When prompted, specify a source file name of
drive:\path\CopyFileUpper.cs
(This is the source file you have just created.)
4. Specify a destination file of Test.cs
5. When the program is finished, use a text editor to examine the Test.cs file. It
should contain a copy of your source code in all uppercase letters.
Module 8: Using Reference-Type Variables 43
u Data Conversions
n Converting Value Types
n Parent/Child Conversions
n The is Operator
n The as Operator
n Conversions and the object Type
n Conversions and Interfaces
n Boxing and Unboxing
This section explains how to perform data conversions between reference types
in C#. You can convert references from one type to another, but the reference
types must be related.
In this section, you will learn about:
n Permitted and prohibited conversions between reference types.
n Conversion mechanisms (casts, is, and as).
n Special considerations for conversion to and from the object type.
n The reflection mechanism, which allows examination of run-time type
information.
n Automatic conversions (boxing and unboxing) between value types and
reference types.
44 Module 8: Using Reference-Type Variables
Converting Value Types
n Implicit Conversions
n Explicit Conversions
l Cast operator
n Exceptions
n System.Convert Class
l Handles the conversions internally
C# supports implicit and explicit data conversions.
Implicit Conversions
For value types, you have learned about two ways to convert data: implicit
conversion and explicit conversion using the cast operator.
Implicit conversion occurs when a value of one type is assigned to another type.
C# only allows implicit conversion for certain combinations of types, typically
when the first value can be converted to the second without any data loss. The
following example shows how data is converted implicitly from int to long:
int a = 4;
long b;
b = a; // Implicit conversion of int to long
Explicit Conversions
You can explicitly convert value types by using the cast operator, as shown:
int a;
long b = 7;
a = (int) b;
Module 8: Using Reference-Type Variables 45
Exceptions
When you use the cast operator, you should be aware that problems might occur
if the value cannot be held in the target variable. If a problem is detected during
an explicit conversion (such as trying to fit the value 9,999,999,999 into an int
variable), C# might raise an exception (in this case, the OverflowException). If
you want, you can catch this exception by using try and catch, as shown:
try {
a = checked((int) b);
}
catch (Exception) {
Console.WriteLine("Problem in cast";
}
For operations that involve integers, use the checked keyword or compile with
the appropriate compiler settings, otherwise checking will not be performed.
System.Convert Class
Conversions between the different base types (such as int, long, and bool) are
handled within the .NET Framework by the System.Convert class.
You do not usually need to make calls to methods of System.Convert. The
compiler handles these calls automatically.

使用道具 举报

回复
论坛徽章:
49
NBA季后赛之星
日期:2014-10-19 19:51:33蓝锆石
日期:2014-10-19 19:51:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33问答徽章
日期:2014-04-15 10:41:44优秀写手
日期:2014-07-24 06:00:11保时捷
日期:2014-10-19 19:51:33三菱
日期:2014-10-19 19:51:33
102#
 楼主| 发表于 2006-8-13 21:33 | 只看该作者
46 Module 8: Using Reference-Type Variables
Parent/Child Conversions
n Conversion to Parent Class Reference
l Implicit or explicit
l Always succeeds
l Can always assign to object
n Conversion to Child Class Reference
l Explicit casting required
l Will check that the reference is of the correct type
l Will raise InvalidCastException if not
You can convert a reference to an object of a child class to an object of its
parent class, and vice versa, under certain conditions.
Conversion to Parent Class Reference
References to objects of one class type can be converted into references to
another type if one class inherits from the other, either directly or indirectly.
A reference to an object can always be converted to a reference to a parent class
object. This conversion can be performed implicitly (by assignment or as part
of an expression) or explicitly (by using the cast operator).
The following examples will use two classes: Animal and Bird. Animal is the
parent class of Bird, or, to put it another way, Bird inherits from Animal.
The following example declares a variable of type Animal and a variable of
type Bird:
Animal a;
Bird b;
Now consider the following assignment, in which the reference in b is copied to
a:
a = b;
The Bird class inherits from the Animal class. Therefore, a method that is
found in Animal is also found in Bird. (The Bird class might have overridden
some of the methods of Animal to create its own version of them, but an
implementation of the method will exist nonetheless.) Therefore, it is possible
for references to Bird objects to be assigned to variables containing references
to values of type Animal.
Module 8: Using Reference-Type Variables 47
In this case, C# performs a type conversion from Bird to Animal. You can
explicitly convert Bird to Animal by using a cast operator, as shown:
a = (Animal) b;
The preceding code will produce exactly the same result.
Conversion to Child Class Reference
You can convert a reference to a child type, but you must explicitly specify the
conversion by using a cast. An explicit conversion is subject to run-time
checking to ensure that the types are compatible, as shown in the following
example:
Bird b = (Bird) a; // Okay
This code will compile successfully. At run time, the cast operator performs a
check to determine whether the value in the variable really is of type Bird. If it
is not, the run-time InvalidCastException is raised.
If you attempt to assign to a child type without a conversion operator, as in the
following code, the compiler will display an error message stating, “Cannot
convert implicitly type ‘Animal’ to type ‘Bird.’”
b = a; // Will not compile
You can trap a type conversion error by using try and catch, just like any other
exception, as shown in the following code:
try {
b = (Bird) a;
}
catch (InvalidCastException) {
Console.WriteLine("Not a bird";
}
48 Module 8: Using Reference-Type Variables
The is Operator
n Returns true If a Conversion Can Be Made
Bird b;
if (a is Bird)
b = (Bird) a; // Safe
else
Console.WriteLine("Not a Bird";
Bird b;
if (a is Bird)
b = (Bird) a; // Safe
else
Console.WriteLine("Not a Bird";
You can handle incompatible types by catching InvalidCastException, but
there are other ways of handling this problem, such as the is operator.
You can use the is operator to test the type of the object without performing a
conversion. The is operator returns true if the value on the left is not null and a
cast to the class on the right, if performed, would complete without throwing an
exception. Otherwise, is returns false.
if (a is Bird)
b = (Bird) a; // Safe, because "a is Bird" returns true
else
Console.WriteLine("Not a Bird";
You can think of the relationship between inherited classes as an “is a kind of”
relationship, as in “A bird is a kind of animal.” References in the variable a
must be references to Animal objects, and b is a kind of animal. Of course, b is
a bird as well, but a bird is just a special case of an animal. The converse is not
true. An animal is not a type of bird. Some animals are birds, but it is not true
that all animals are birds.
So the following expression can be read as “If a is a kind of bird,” or “If a is a
bird or a type derived from bird.”
if (a is bird)

使用道具 举报

回复
论坛徽章:
49
NBA季后赛之星
日期:2014-10-19 19:51:33蓝锆石
日期:2014-10-19 19:51:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33问答徽章
日期:2014-04-15 10:41:44优秀写手
日期:2014-07-24 06:00:11保时捷
日期:2014-10-19 19:51:33三菱
日期:2014-10-19 19:51:33
103#
 楼主| 发表于 2006-8-13 21:33 | 只看该作者
Module 8: Using Reference-Type Variables 49
The as Operator
n Converts Between Reference Types, Like Cast
n On Error
l Returns null
l Does not raise an exception
Bird b = a as Bird; // Convert
if (b == null)
Console.WriteLine("Not a bird";
Bird b = a as Bird; // Convert
if (b == null)
Console.WriteLine("Not a bird";
You can use the as operator to perform conversions between types.
Example
The following statement performs a conversion of the reference in a to a value
that references a class of type Bird, and the runtime automatically checks to
ensure that the conversion is acceptable.
b = a as Bird;
Error Handling
The as operator differs from the cast operator in the way it handles errors. If, in
the preceding example, the reference in variable a cannot be converted in a
reference to an object of class Bird, the value null is stored in b, and the
program continues. The as operator never raises an exception.
You can rewrite the previous code as follows to display an error message if the
conversion cannot be performed:
Bird b = a as Bird;
if (b == null)
Console.WriteLine("Not a bird";
Although as never raises an exception, any attempt to access through the
converted value will raise a NullReferenceException if it is null. Therefore,
you should always chec k the return value from as.
50 Module 8: Using Reference-Type Variables
Conversions and the object Type
n The object Type Is the Base for All Classes
n Any Reference Can Be Assigned to object
n Any object Variable Can Be Assigned to Any Reference
l With appropriate type conversion and checks
n The object Type and is
object ox;
ox = a;
ox = (object) a;
ox = a as object;
object ox;
ox = a;
ox = (object) a;
ox = a as object;
b = (Bird) ox;
b = ox as Bird;
b = (Bird) ox;
b = ox as Bird;
All reference types are based on the object type. This means that any reference
can be stored in a variable of type object.
The object Type Is the Base for All Classes
The object type is the base for all reference types.
Any Reference Can Be Assigned to object
Because all classes are based directly or indirectly on the object type, you can
assign any reference to a variable of type object, either with an implicit
conversion or with a cast. The following code provides an example:
object ox;
ox = a;
ox = (object) a;
ox = a as object;
Any object Variable Can Be Assigned to Any Reference
You can assign a value of type object to any other object reference, if you cast
it correctly. Remember that the run-time system will perform a check to ensure
that the value being assigned is of the correct type. The following code provides
an example:
b = (Bird) ox;
b = ox as Bird;
Module 8: Using Reference-Type Variables 51
The preceding examples can be written with full error checking as follows:
try {
b = (Bird) ox;
}
catch (InvalidCastException) {
Console.WriteLine("Cannot convert to Bird";
}
b = ox as Bird;
if (b == null)
Console.WriteLine("Cannot convert to Bird";
The object Type and is
Because every value is derived ultimately from object, checking a value with
the is operator to see if it is an object will always return true.
if (a is object) // Always returns true

使用道具 举报

回复
论坛徽章:
49
NBA季后赛之星
日期:2014-10-19 19:51:33蓝锆石
日期:2014-10-19 19:51:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33问答徽章
日期:2014-04-15 10:41:44优秀写手
日期:2014-07-24 06:00:11保时捷
日期:2014-10-19 19:51:33三菱
日期:2014-10-19 19:51:33
104#
 楼主| 发表于 2006-8-13 21:34 | 只看该作者
52 Module 8: Using Reference-Type Variables
Conversion and Interfaces
n An Interface Can Only Be Used to Access Its Own
Members
n Other Methods and Variables of the Class Are Not
Accessible Through the Interface
You can perform conversions by using the casting operators, as and is, when
working with interfaces.
For example, you can declare a variable of an interface type, as shown:
IHashCodeProvider hcp;
Converting a Reference to an Interface
You can use the cast operator to convert the object reference into a reference to
a given interface, as shown:
IHashCodeProvider hcp;
hcp = (IHashCodeProvider) x;
As with conversion between class references, the cast operator will raise an
InvalidCastException if the object provided does not implement the interface.
You should determine whether an object supports an interface before casting
the object, or use try and catch to trap the exception.
Determining Whether an Interface Is Implemented
You can use the is operator to determine whether an object supports an
interface. The syntax is the same as the syntax used for classes:
if (x is IHashCodeProvider) ...
Module 8: Using Reference-Type Variables 53
Using the as Operator
You can also use the as operator as an alternative to casting, as shown:
IHashCodeProvider hcp;
hcp = x as IHashCodeProvider;
As with conversion between classes, if the reference that is being converted
does not support the interface, the as operator returns null.
After you have converted a reference to a class into a reference to an interface,
the new reference can only access members of that interface, and cannot access
the other public members of the class.
Example
Consider the following example to learn how converting references to
interfaces works. Suppose you have created an interface called IVisual that
specifies a method called Paint, as follows:
interface IVisual
{
void Paint( );
}
Suppose that you also have a Rectangle class that implements the IVisual
interface. It implements the Paint method, but it can also define its own
methods. In this example, Rectangle has defined an additional method called
Move that is not part of IVisual.
You can create a Rectangle , r, and use its Move and Paint methods, as you
would expect. You can even reference it through an IVisual variable, v.
However, despite the fact that v and r both refer to the same object in memory,
you cannot call the Move method by using v because it is not part of the
IVisual interface. The following code provides examples:
Rectangle r = new Rectangle( );
r.Move( ); // Okay
r.Paint( ); // Okay
IVisual v = (IVisual) r;
v.Move( ); // Not valid
v.Paint( ); // Okay
54 Module 8: Using Reference-Type Variables
Boxing and Unboxing
n Unified Type System
n Boxing
n Unboxing
n Calling Object Methods on Value Types
int p = 123;
object box;
box = p;
int p = 123;
object box;
box = p;
?? 112233
112233 pp == ((iinntt))bbooxx;;
C# can convert value types into object references and object references into
value types.
Unified Type System
C# has a unified type system that allows value types to be converted to
references of type object and object references to be converted into value types.
Value types can be converted into references of type object, and vice versa.
Values of types like int and bool can therefore be handled as simple values most
of the time. This is normally the most efficient technique because there is none
of the overhead that is associated with references. However, when you want to
use these values as if they were references, they can be temporarily boxed for
you to do so.
Boxing
Expressions of value types can also be converted to values of type object , and
back again. When a variable of value type needs to be converted to object type,
an object box is allocated to hold the value and the value is copied into the box.
This process is known as boxing.
int p = 123;
object box;
box = p; // Boxing (implicit)
box = (object) p; // Boxing (explicit)
The boxing operation can be done implicitly, or explicitly with a cast to an
object. Boxing occurs most typically when a value type is passed to a parameter
of type object.
Module 8: Using Reference-Type Variables 55
Unboxing
When a value in an object is converted back into a value type, the value is
copied out of the box and into the appropriate storage location. This process is
known as unboxing.
p = (int) box; // Unboxing
You must perform unboxing with an explicit cast operator.
If the value in the reference is not the exact type of the cast, the cast will raise
an InvalidCastException.
Calling Object Methods on Value Types
Because boxing can take place implicitly, you can call methods of the object
type on any variable or expression, even those having value types. The
following code provides an example:
static void Show(object o)
{
Console.WriteLine(o.ToString( ));
}
Show(42);
This works because the value 42 is implicitly boxed into an object parameter,
and the ToString method of this parameter is then called.
It produces the same result as the following code:
object o = (object) 42; // Box
Console.WriteLine(o.ToString( ));
Boxing does not occur when you call Object methods directly on a value.
For example, the expression 42.ToString( ) does not box 42 into an object .
This is because the compiler can statically determine the type and discerns
which method to call.
Note

使用道具 举报

回复
论坛徽章:
49
NBA季后赛之星
日期:2014-10-19 19:51:33蓝锆石
日期:2014-10-19 19:51:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33问答徽章
日期:2014-04-15 10:41:44优秀写手
日期:2014-07-24 06:00:11保时捷
日期:2014-10-19 19:51:33三菱
日期:2014-10-19 19:51:33
105#
 楼主| 发表于 2006-8-13 21:34 | 只看该作者
56 Module 8: Using Reference-Type Variables
Multimedia: Type-Safe Casting
Module 8: Using Reference-Type Variables 57
Lab 8.2 Converting Data
Objectives
After completing this lab, you will be able to:
n Convert values of one reference type to another.
n Test whether a reference variable supports a given interface.
Prerequisites
Before working on this lab, you should be familiar with the following:
n Concepts of object-oriented programming
n Creating classes
n Defining methods
Estimated time to complete this lab: 30 minutes
58 Module 8: Using Reference-Type Variables
Exercise 1
Testing for the Implementation of an Interface
In this exercise, you will add a static method called IsItFormattable to the
Utils class that you created in Lab 5. If you did not complete that lab, you can
obtain a copy of the class in the install folder\Labs\Lab08\Starter folder.
The IsItFormattable method takes one parameter of type object and tests
whether that parameter implements the System.IFormattable interface. If the
object does have this interface, the method will return true. Otherwise, it will
return false.
A class implements the System.IFormattable interface to return a string
representation of an instance of that class. Base types such as int and ulong
implement this interface (after the value has been boxed). Many reference types,
for example string, do not. User-defined types can implement the interface if
the developer requires it. For more information about this interface, consult
the .NET Framework SDK Help documentation.
You will write test code that will call the Utils.IsItFormattable method with
arguments of different types and display the results on the screen.
? To create the IsItFormattable method
1. Open the InterfaceTest.sln project in the install folder\
Labs\Lab08\Starter\InterfaceTest folder.
2. Edit the Utils class as follows:
a. Create a public static method called IsItFormattable in the Utils class.
b. This method takes one parameter called x of type object that is passed
by value. The method returns a bool.
c. Use the is operator to determine whether the passed object s upports the
System.IFormattable interface. If it does, return true; otherwise return
false.
The completed method should be as follows:
using System;
...
class Utils
{
public static bool IsItFormattable(object x)
{
// Use the is operator to test whether the
// object has the IFormattable interface
if (x is IFormattable)
return true;
else
return false;
}
}
Module 8: Using Reference-Type Variables 59
? To test the IsItFormattable method
1. Edit the file Test class.
2. In the Main method, declare and initialize variables of types int, ulong, and
string.
3. Pass each variable to Utils.IsItFormattable(), and print the result from each
call.
4. The class Test might be as follows:
using System;
class Test
{
static void Main( )
{
int i=0;
ulong ul=0;
string s = "Test";
Console.WriteLine("int: {0}",
êUtils.IsItFormattable(i));
Console.WriteLine("ulong: {0}",
êUtils.IsItFormattable(ul));
Console.WriteLine("String: {0}",
êUtils.IsItFormattable(s));
}
}
5. Compile and test the code. You should see true for the int and ulong values,
and false for the string value.
60 Module 8: Using Reference-Type Variables
Exercise 2
Working with Interfaces
In this exercise, you will write a Display method that will use the as operator to
determine whether the object passed as a parameter supports a user-defined
interface called IPrintable and call a method of that interface if it is supported.
? To create the Display method
1. Open the TestDisplay.sln project in the install folder\
Labs\Lab08\Starter\TestDisplay folder.
The starter code includes the definition for an interface called IPrintable,
which contains a method called Print. A class that implements this interface
should use the Print method to display to the console the values held inside
the object. Also defined in the starter code files is a class called Coordinate
that implements the IPrintable interface.
A Coordinate object holds a pair of numbers that can define a position in
two-dimensional space. You do not need to understand how the Coordinate
class works (although you might want to look at it). All you need to know is
that it implements the IPrintable interface and that you can use the Print
method to display its contents.
2. Edit the Utils class as follows:
a. Add a public static void method called Display in the Utils class. This
method should take one parameter, an object passed by value, called
item.
b. In Display, declare an interface variable called ip of type IPrintable.
c. Convert the reference in the parameter item into a reference to the
IPrintable interface that uses the as operator. Store the result in ip.
d. If the value of ip is not null, use the IPrintable interface to call Print. If
it is null, the object does not support the interface. In this case, use
Console.WriteLine to display to results of the ToString method on the
parameter instead.
The completed method should be as follows:
public static void Display(object item)
{
IPrintable ip;
ip = (item as IPrintable);
if (ip != null)
ip.Print( );
else
Console.WriteLine(item.ToString( ));
}

使用道具 举报

回复
论坛徽章:
49
NBA季后赛之星
日期:2014-10-19 19:51:33蓝锆石
日期:2014-10-19 19:51:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33问答徽章
日期:2014-04-15 10:41:44优秀写手
日期:2014-07-24 06:00:11保时捷
日期:2014-10-19 19:51:33三菱
日期:2014-10-19 19:51:33
106#
 楼主| 发表于 2006-8-13 21:34 | 只看该作者
Module 8: Using Reference-Type Variables 61
? To test the Display method
1. Within the Main method in the Test class, create a variable of type int, a
variable of type string, and a variable of type Coordinate. To initialize the
Coordinate variable, you can use the two-parameter constructor:
Coordinate c = new Coordinate(21.0, 68.0);
2. Pass these three variables, in turn, to Utils.Display to print them out.
3. The code should be as follows:
class Test
{
static void Main( )
{
int num = 65;
string msg = "A String";
Coordinate c = new Coordinate(21.0,68.0);
Utils.Display(num);
Utils.Display(msg);
Utils.Display(c);
}
}
4. Compile and test your application.
62 Module 8: Using Reference-Type Variables
If Time Permits
Testing the Method
If you want to try the IsItFormattable method that you created in Exercise 1
with a user -defined class, use the BankAccount class that you developed in a
previous lab.
Re-write the Display method from Exercise 2 by using the cast operator.
Remember to catch any InvalidCastException that C# might throw in response
to errors.
Module 8: Using Reference-Type Variables 63
Review
n Using Reference-Type Variables
n Using Common Reference Types
n The Object Hierarchy
n Namespaces in the .NET Framework
n Data Conversions
1. Explain how a memory is allocated and de-allocated for a variable of
reference type.
2. What special value indicates that a reference variable does not contain a
reference to an object? What happens if you try to access a reference
variable with this value?
3. List the key features of the String class.
4. What type is the base type for all classes?
64 Module 8: Using Reference-Type Variables
5. Explain the difference between the cast operator and the as operator when
used to convert between class references.
6. List ways in which you can determine the type of an object.

使用道具 举报

回复
论坛徽章:
49
NBA季后赛之星
日期:2014-10-19 19:51:33蓝锆石
日期:2014-10-19 19:51:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33问答徽章
日期:2014-04-15 10:41:44优秀写手
日期:2014-07-24 06:00:11保时捷
日期:2014-10-19 19:51:33三菱
日期:2014-10-19 19:51:33
107#
 楼主| 发表于 2006-8-13 21:35 | 只看该作者
Contents
Overview 1
Using Constructors 2
Initializing Data 13
Lab 9.1: Creating Objects 31
Objects and Memory 39
Using Destructors 45
Lab 9.2: Destroying Objects 60
Review 65
Module 9: Creating and
Destroying Objects
This course is based on the prerelease Beta 1 version of Microsoft? Visual Studio .NET.
Content in the final release of the course may be different from the content included in
this prerelease version. All labs in the course are to be completed with the Beta 1
version of Visual Studio .NET.
Information in this document is subject to change without notice. The names of companies,
products, people, characters, and/or data mentioned herein are fictitious and are in no way intended
to represent any real individual, company, product, or event, unless otherwise noted. Complying
with all applicable copyright laws is the responsibility of the user. No part of this document may
be reproduced or transmitted in any form or by any means, electronic or mechanical, for any
purpose, without the expre ss written permission of Microsoft Corporation. If, however, your only
means of access is electronic, permission to print one copy is hereby granted.
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.
ó 2001 Microsoft Corporation. All rights reserved.
Microsoft, ActiveX, BizTalk, IntelliSense, JScript, Microsoft Press, MSDNPowerPoint, Visual
Basic, Visual C++, Visual C#, Visual Studio, Windows, and Windows Media are either registered
trademarks or trademarks of Microsoft Corporation in the U.S.A. and/or other countries.
Other product and company names mentioned herein may be the trademarks of their respective
owners.
Module 9: Creating and Destroying Objects 1
Overview
n Using Constructors
n Initializing Data
n Objects and Memory
n Using Destructors
In this module, you will learn what happens when an object is created, how to
use constructors to initialize objects, and how to use destructors to destroy
objects. You will also learn what happens when an object is destroyed and how
garbage collection reclaims memory.
After completing this module, you will be able to:
n Use constructors to initialize objects.
n Create overloaded constructors that can accept varying parameters.
n Describe the lifetime of an object and what happens when it is destroyed.
n Create destructors and use Finalize methods.
2 Module 9: Creating and Destroying Objects
u Using Constructors
n Creating Objects
n Using the Default Constructor
n Overriding the Default Constructor
n Overloading Constructors
Constructors are special methods that you use to initialize objects when you
create them. Even if you do not write a constructor yourself, a default
constructor is provided for you whenever you create an object from a reference
type. In this section, you will learn how to use constructors to control what
happens when an object is created.
Module 9: Creating and Destroying Objects 3
Creating Objects
n Step 1: Allocating Memory
l Use new operator to allocate memory from the heap
n Step 2: Initializing the Object with a Constructor
l Use the name of the class followed by parentheses
DDaattee wwhheenn == nneeww DDaattee(( ));;
s
The process of creating an object in C# involves two steps:
1. Use the new keyword to acquire and allocate memory for the object.
2. Write a constructor to turn the memory acquired by new into an object.
Even though there are two steps in this process, you must perform both steps in
one line of code. For example, if Date is the name of a class, use the following
syntax to allocate memory and initialize the object when.
Date when = new Date( );
Step 1: Allocating Memory
The first step in creating an object is to allocate memory for the object. All
objects are created by using the new operator. There are no exceptions to this
rule. You can do this explicitly in your code, or the compiler will do it for you.
In the following table, you can see examples of code and what they represent.
Code example Represents
string s = "Hello"; string s = new string("Hello";
int[ ] array = {1,2,3,4}; int[ ] array = new int[4]{1,2,3,4};

使用道具 举报

回复
论坛徽章:
49
NBA季后赛之星
日期:2014-10-19 19:51:33蓝锆石
日期:2014-10-19 19:51:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33问答徽章
日期:2014-04-15 10:41:44优秀写手
日期:2014-07-24 06:00:11保时捷
日期:2014-10-19 19:51:33三菱
日期:2014-10-19 19:51:33
108#
 楼主| 发表于 2006-8-13 21:36 | 只看该作者
4 Module 9: Creating and Destroying Objects
How new Affects Performance
Generally, there are only two functions of new that affect performance:
n A Boolean test
The heap is a contiguous block of memory of known size. A special pointer
marks the current position in the heap for memory allocation purposes. All
memory to one side of the position has already been allocated by new. All
memory to the other side of the position is still available. The Boolean test
simply uses the difference between this position and the end of the heap to
determine how many bytes of free memory are left in the heap. It then
compares this amount to the number of bytes requested by new.
n A pointer increment
If there are enough free bytes left in the heap, the special pointer is
incremented by the number of bytes requested, thus marking the memory as
allocated. The address of the allocated block is then returned.
This makes the dynamic allocation of heap memory essentially as fast as the
dynamic allocation of stack memory.
Strictly speaking, this is only true if there is only one variable. If there
are multiple variables, the stack-based variables will be allocated all at once,
but the heap variables will require multiple allocations.
Step 2: Initializing the Object with a Constructor
The second step in creating an object is to write a constructor. A constructor
turns the memory allocated by new into an object. There are two types of
constructors: instance constructors and static constructors. Instance constructors
are constructors that initialize objects. Static constructors are constructors that
initialize classes.
How new and Instance Constructors Collaborate
It is important to realize how closely new and instance constructors collaborate
to create objects. The only purpose of new is to acquire raw uninitialized
memory. The only purpose of an instance constructor is to initialize the
memory and convert it into an object that is ready to use. Specifically, new is
not involved with initialization in any way, and instance constructors are not
involved in acquiring memory in any way.
Although new and instance constructors perform separate tasks, as a
programmer you cannot use them separately. This is one way for C# to help
guarantee that memory is always definitely set to a valid value before it is read.
(This is called definite assignment.)
In C++, you can allocate memory and not initialize
it (by directly calling operator new). You can also initialize memory allocated
previously (by using placement new). This separation is not possible in C#.
Note
Note to C++ Programmers
Module 9: Creating and Destroying Objects 5
Using the Default Constructor
n Features of a Default Constructor
l Public accessibility
l Same name as the class
l No return type— not even void
l Expects no arguments
l Initializes all fields to zero, false or null
n Constructor Syntax
ccllaassss DDaattee {{ ppuubblliicc DDaattee(( )) {{ ...... }} }}
When you create an object, the C# compiler provides a default constructor if
you do not write one yourself. Consider the following example:
class Date
{
private int ccyy, mm, dd;
}
class Test
{
static void Main( )
{
Date when = new Date( );
...
}
}
The statement inside Test.Main creates a Date object called when by using
new (which allocates memory from the heap) and by calling a special method
that has the same name as the class (the instance constructor). However, the
Date class does not declare an instance constructor. (It does not declare any
methods at all.) By default, the compiler automatically generates a default
instance constructor.

使用道具 举报

回复
论坛徽章:
49
NBA季后赛之星
日期:2014-10-19 19:51:33蓝锆石
日期:2014-10-19 19:51:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33问答徽章
日期:2014-04-15 10:41:44优秀写手
日期:2014-07-24 06:00:11保时捷
日期:2014-10-19 19:51:33三菱
日期:2014-10-19 19:51:33
109#
 楼主| 发表于 2006-8-13 21:36 | 只看该作者
6 Module 9: Creating and Destroying Objects
Features of a Default Constructor
Conceptually, the instance constructor that the compiler generates for the Date
class looks like the following example:
class Date
{
public Date( )
{
ccyy = 0;
mm = 0;
dd = 0;
}
private int ccyy, mm, dd;
}
The constructor has the following features:
n Same name as the class name
By definition, an instance constructor is a method that has the same name as
its class. This is a natural and intuitive definition and matches the syntax
that you have already seen. Following is an example:
Date when = new Date( );
n No return type
This is the second defining characteristic of a constructor. A constructor
never has a return type— not even void.
n No arguments required
It is possible to declare constructors that take arguments. However, the
default constructor generated by the compiler expects no arguments.
n All fields initialized to zero
This is important. The compiler-generated default constructor implicitly
initializes all non-static fields as follows:
· Numeric fields (such as int, double, and decimal) are initialized to zero.
· Fields of type bool are initialized to false.
· Reference types (covered in an earlier module) are initialized to null.
· Fields of type struct are initialized to contain zero values in all their
elements.
n Public accessibility
This allows new instances of the object to be created.
In Module 10, “Inheritance in C#,” in Course 2124A, Introduction to C#
Programming for the Microsoft .NET Platform (Prerelease), you will learn
about abstract classes. The compiler-generated default constructor for an
abstract class has protected access.
Note
Module 9: Creating and Destroying Objects 7
Overriding the Default Constructor
n The Default Constructor Might Be Inappropriate
l If so, do not use it; write your own!
class Date
{
public Date( )
{
ccyy = 1970;
mm = 1;
dd = 1;
}
private int ccyy, mm, dd;
}
class Date
{
public Date( )
{
ccyy = 1970;
mm = 1;
dd = 1;
}
private int ccyy, mm, dd;
}
Sometimes it is not appropriate for you to use the compiler-generated default
constructor. In these cases, you can write your own constructor that contains
only the code to initialize fields to non-zero values. Any fields that you do not
initialize in your constructor will retain their default initialization of zero.
What If the Default Constructor Is Inappropriate?
There are several cases in which the compiler-generated default constructor
may be inappropriate:
n Public access is sometimes inappropriate.
The Factory Method pattern uses a non-public constructor. (The Factory
Method pattern is discussed in Design Patterns: Elements of Reusable
Object-Oriented Software, by E. Gamma, R. Helm, R. Johnson, and J.
Vlissides. It is covered in a later module.)
Procedural functions (such as Cos and Sin) often use private constructors.
The Singleton pattern typically uses a private constructor. (The Singleton
pattern is also covered in Design Patterns: Elements of Reusable Object-
Oriented Software and in a later topic in this section.)
n Zero initialization is sometimes inappropriate.
Consider the compiler-generated default constructor for the following Date
class:
class Date
{
private int ccyy, mm, dd;
}
The default constructor will initialize the year field (ccyy) to zero, the month
field (mm) to zero, and the day field (dd) to zero. This might not be
appropriate if you want the date to default to a different value.

使用道具 举报

回复
论坛徽章:
49
NBA季后赛之星
日期:2014-10-19 19:51:33蓝锆石
日期:2014-10-19 19:51:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33指数菠菜纪念章
日期:2014-10-19 19:52:33问答徽章
日期:2014-04-15 10:41:44优秀写手
日期:2014-07-24 06:00:11保时捷
日期:2014-10-19 19:51:33三菱
日期:2014-10-19 19:51:33
110#
 楼主| 发表于 2006-8-13 21:36 | 只看该作者
8 Module 9: Creating and Destroying Objects
n Invisible code is hard to maintain
You cannot see the default constructor code. This can occasionally be a
problem. For example, you cannot single -step through invisible code when
debugging. Additionally, if you choose to use the default initialization to
zero, how will developers who need to maintain the code know that this
choice was deliberate?
Writing Your Own Default Constructor
If the compiler-generated default constructor is inappropriate, you must write
your own default constructor. The C# language helps you to do this.
You can write a constructor that only contains the code to initialize fields to
non-zero values. All fields that are not initialized in your constructor retain their
default initialization to zero. The following code provides an example:
class DefaultInit
{
public int a, b;
public DefaultInit( )
{
a = 42;
// b retains default initia lization to zero
}
}
class Test
{
static void Main( )
{
DefaultInit di = new DefaultInit( );
Console.WriteLine(di.a); // Writes 42
Console.WriteLine(di.b); // Writes zero
}
}
You should be wary of doing more than simple initializations in your own
constructors. You must consider potential failure: the only sensible way you can
signal an initialization failure in a constructor is by throwing an exception.
The same is also true for operators. Operators are discus sed in Module 12,
“Operators, Delegates, and Events,” in Course 2124A, Introduction to C#
Programming for the Microsoft .NET Platform (Prerelease).
When initialization succeeds, you have an object that you can use. If
initialization fails, you do not have an object.
Note
Module 9: Creating and Destroying Objects 9
Overloading Constructors
n Constructors Are Methods; They Can Be Overloaded
l Same scope, same name, different parameters
l Allows objects to be initialized in different ways
n WARNING
l If you write a constructor for a class, the compiler does
not create a default constructor
class Date
{
public Date( ) { ... }
public Date(int year, int month, int day) { ... }
...
}
class Date
{
public Date( ) { ... }
public Date(int year, int month, int day) { ... }
...
}
Constructors are special kinds of methods. Just as you can overload methods,
you can overload constructors.
What Is Overloading?
Overloading is the technical term for declaring two or more methods in the
same scope w ith the same name. The following code provides an example:
class Overload
{
public void Method ( ) { ... }
public void Method (int x) { ... }
}
class Use
{
static void Main( )
{
Overload o = new Overload( );
o.Method( );
o.Method(42);
}
}
In this code example, two methods called Method are declared in the scope of
the Overload class, and both are called in Use.Main. There is no ambiguity,
because the number and types of the arguments determine which method is
called.

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表